Spaces:
Sleeping
Sleeping
Update app.py from anycoder
Browse files
app.py
ADDED
|
@@ -0,0 +1,415 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import time
|
| 3 |
+
import json
|
| 4 |
+
import hashlib
|
| 5 |
+
import base64
|
| 6 |
+
import random
|
| 7 |
+
import requests
|
| 8 |
+
from datetime import datetime
|
| 9 |
+
from typing import Optional, Dict, Any, List, Tuple
|
| 10 |
+
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
|
| 11 |
+
|
| 12 |
+
import gradio as gr
|
| 13 |
+
import cirq
|
| 14 |
+
import numpy as np
|
| 15 |
+
|
| 16 |
+
# ---------- Konfigurasi ----------
|
| 17 |
+
PINATA_API_KEY = os.getenv("PINATA_API_KEY", "85065bbe4e7068ff455d")
|
| 18 |
+
PINATA_SECRET_KEY = os.getenv("PINATA_SECRET_KEY", "7bf252357066397403574b2a707524a60b1f60bfba9cf4b6ac9e6426d59cbd75")
|
| 19 |
+
|
| 20 |
+
# ---------- BIP39 Word List ----------
|
| 21 |
+
BIP39 = ["abandon","ability","able","about","above","absent","absorb","abstract","absurd","abuse","access","accident","account","accuse","achieve","acid","acoustic","acquire","across","act","action","actor","actress","actual","adapt","add","addict","address","adjust","admit","adult","advance","advice","aerobic","affair","afford","afraid","africa","after","again","age","agent","agree","ahead","aim","air","airport","aisle","alarm","album","alcohol","alert","alien","all","alley","allow","almost","alone","alpha","already","also","alter","always","amateur","amazing","among","amount","amused","analyst","anchor","ancient","anger","angle","angry","animal","ankle","announce","annual","another","answer","antenna","antique","anxiety","any","apart","apology","appear","apple","approve","april","arch","arctic","area","arena","argue","arm","armed","armor","army","around","arrange","arrest","arrive","arrow","art","artefact","artist","artwork","ask","aspect","assault","asset","assist","assume","asthma","athlete","atom","attack","attend","attitude","attract","auction","audit","august","aunt","author","auto","autumn","average","avocado","avoid","awake","aware","away","awesome","awful","awkward","axis","baby","bachelor","bacon","badge","bag","balance","balcony","ball","bamboo","banana","banner","bar","barely","bargain","barrel","base","basic","basket","battle","beach","bean","beauty","because","become","beef","before","begin","behave","behind","believe","below","belt","bench","benefit","best","betray","better","between","beyond","bicycle","bid","bike","bind","biology","bird","birth","bitter","black","blade","blame","blanket","blast","bleak","bless","blind","blood","blossom","blouse","blue","blur","blush","board","boat","body","boil","bomb","bone","bonus","book","boost","border","boring","borrow","boss","bottom","bounce","box","boy","bracket","brain","brand","brass","brave","bread","breeze","brick","bridge","brief","bright","bring","brisk","broccoli","broken","bronze","broom","brother","brown","brush","bubble","buddy","budget","buffalo","build","bulb","bulk","bullet","bundle","bunker","burden","burger","burst","bus","business","busy","butter","buyer","buzz","cabbage","cabin","cable","cactus","cage","cake","call","calm","camera","camp","can","canal","cancel","candy","cannon","canoe","canvas","canyon","capable","capital","captain","car","carbon","card","cargo","carpet","carry","cart","case","cash","casino","castle","casual","cat","catalog","catch","category","cattle","caught","cause","caution","cave","ceiling","celery","cement","census","century","cereal","certain","chair","chalk","champion","change","chaos","chapter","charge","chase","chat","cheap","check","cheese","chef","cherry","chest","chicken","chief","child","chimney","choice","choose","chronic","chuckle","chunk","churn","cigar","cinnamon","circle","citizen","city","civil","claim","clap","clarify","claw","clay","clean","clerk","clever","click","client","cliff","climb","clinic","clip","clock","clog","close","cloth","cloud","clown","club","clump","cluster","clutch","coach","coast","coconut","code","coffee","coil","coin","collect","color","column","combine","come","comfort","comic","common","company","concert","conduct","confirm","congress","connect","consider","control","convince","cook","cool","copper","copy","coral","core","corn","correct","cost","cotton","couch","country","couple","course","cousin","cover","coyote","crack","cradle","craft","cram","crane","crash","crater","crawl","crazy","cream","credit","creek","crew","cricket","crime","crisp","critic","crop","cross","crouch","crowd","crucial","cruel","cruise","crumble","crunch","crush","cry","crystal","cube","culture","cup","cupboard","curious","current","curtain","curve","cushion","custom","cute","cycle","dad","damage","damp","dance","danger","daring","dash","daughter","dawn","day","deal","debate","debris","decade","december","decide","decline","decorate","decrease","deer","defense","define","defy","degree","delay","deliver","demand","demise","denial","dentist","deny","depart","depend","deposit","depth","deputy","derive","describe","desert","design","desk","despair","destroy","detail","detect","develop","device","devote","diagram","dial","diamond","diary","dice","diesel","diet","differ","digital","dignity","dilemma","dinner","dinosaur","direct","dirt","disagree","discover","disease","dish","dismiss","disorder","display","distance","divert","divide","divorce","dizzy","doctor","document","dog","doll","dolphin","domain","donate","donkey","donor","door","dose","double","dove","draft","dragon","drama","drastic","draw","dream","dress","drift","drill","drink","drip","drive","drop","drum","dry","duck","dumb","dune","during","dust","dutch","duty","dwarf","dynamic","eager","eagle","early","earn","earth","easily","east","easy","echo","ecology","economy","edge","edit","educate","effort","egg","eight","either","elbow","elder","electric","elegant","element","elephant","elevator","elite","else","embark","embody","embrace","emerge","emotion","employ","empower","empty","enable","enact","end","endless","endorse","enemy","energy","enforce","engage","engine","enhance","enjoy","enlist","enough","enrich","enroll","ensure","enter","entire","entry","envelope","episode","equal","equip","era","erase","erode","erosion","error","erupt","escape","essay","essence","estate","eternal","ethics","evidence","evil","evoke","evolve","exact","example","excess","exchange","excite","exclude","excuse","execute","exercise","exhaust","exhibit","exile","exist","exit","exotic","expand","expect","expire","explain","expose","express","extend","extra","eye","eyebrow","fabric","face","faculty","fade","faint","faith","fall","false","fame","family","famous","fan","fancy","fantasy","farm","fashion","fat","fatal","father","fatigue","fault","favorite","feature","february","federal","fee","feed","feel","female","fence","festival","fetch","fever","few","fiber","fiction","field","figure","file","film","filter","final","find","fine","finger","finish","fire","firm","first","fiscal","fish","fit","fitness","fix","flag","flame","flash","flat","flavor","flee","flight","flip","float","flock","floor","flower","fluid","flush","fly","foam","focus","fog","foil","fold","follow","food","foot","force","forest","forget","fork","fortune","forum","forward","fossil","foster","found","fox","fragile","frame","frequent","fresh","friend","fringe","frog","front","frost","frown","frozen","fruit","fuel","fun","funny","furnace","fury","future","gadget","gain","galaxy","gallery","game","gap","garage","garbage","garden","garlic","garment","gas","gasp","gate","gather","gauge","gaze","general","genius","genre","gentle","genuine","gesture","ghost","giant","gift","giggle","ginger","giraffe","girl","give","glad","glance","glare","glass","glide","glimpse","globe","gloom","glory","glove","glow","glue","goat","goddess","gold","good","goose","gorilla","gospel","gossip","govern","gown","grab","grace","grain","grant","grape","grass","gravity","great","green","grid","grief","grit","grocery","group","grow","grunt","guard","guess","guide","guilt","guitar","gun","gym","habit","hair","half","hammer","hamster","hand","happy","harbor","hard","harsh","harvest","hat","have","hawk","hazard","head","health","heart","heavy","hedgehog","height","hello","helmet","help","hen","hero","hidden","high","hill","hint","hip","hire","history","hobby","hockey","hold","hole","holiday","hollow","home","honey","hood","hope","horn","horror","horse","hospital","host","hotel","hour","hover","hub","huge","human","humble","humor","hundred","hungry","hunt","hurdle","hurry","hurt","husband","hybrid","ice","icon","idea","identify","idle","ignore","ill","illegal","illness","image","imitate","immense","immune","impact","impose","improve","impulse","inch","include","income","increase","index","indicate","indoor","industry","infant","inflict","inform","inhale","inherit","initial","inject","injury","inmate","inner","innocent","input","inquiry","insane","insect","inside","inspire","install","intact","interest","into","invest","invite","involve","iron","island","isolate","issue","item","ivory","jacket","jaguar","jar","jazz","jealous","jeans","jelly","jewel","job","join","joke","journey","joy","judge","juice","jump","jungle","junior","junk","just","kangaroo","keen","keep","ketchup","key","kick","kid","kidney","kind","kingdom","kiss","kit","kitchen","kite","kitten","kiwi","knee","knife","knock","know","lab","label","labor","ladder","lady","lake","lamp","language","laptop","large","later","latin","laugh","laundry","lava","law","lawn","lawsuit","layer","lazy","leader","leaf","learn","leave","lecture","left","leg","legal","legend","leisure","lemon","lend","length","lens","leopard","lesson","letter","level","liar","liberty","life","lift","light","like","limb","limit","link","lion","liquid","list","little","live","lizard","load","loan","lobster","local","lock","logic","lonely","long","loop","lottery","loud","lounge","love","loyal","lucky","luggage","lumber","lunar","lunch","luxury","lyrics","machine","mad","magic","magnet","maid","mail","main","major","make","mammal","man","manage","mandate","mango","mansion","manual","maple","marble","march","margin","marine","market","marriage","mask","mass","master","match","material","math","matrix","matter","maximum","maze","meadow","mean","measure","meat","mechanic","medal","media","melody","melt","member","memory","mention","menu","mercy","merge","merit","merry","mesh","message","metal","method","middle","midnight","milk","million","mimic","mind","minimum","minor","minute","miracle","mirror","misery","miss","mistake","mix","mixed","mixture","mobile","model","modify","mom","moment","monitor","monkey","monster","month","moon","moral","more","morning","mosquito","mother","motion","motor","mountain","mouse","move","movie","much","muffin","mule","multiply","muscle","museum","mushroom","music","must","mutual","myself","mystery","myth","naive","name","napkin","narrow","nasty","nation","nature","near","neck","need","negative","neglect","neither","nephew","nerve","nest","net","network","neutral","never","news","next","nice","night","noble","noise","nominee","noodle","normal","north","nose","notable","note","nothing","notice","novel","now","nuclear","number","nurse","nut","oak","obey","object","oblige","obscure","observe","obtain","obvious","occur","ocean","october","odor","off","offer","office","often","oil","okay","old","olive","olympic","omit","once","one","onion","online","only","open","opera","opinion","oppose","option","orange","orbit","orchard","order","ordinary","organ","orient","original","orphan","ostrich","other","outdoor","outer","output","outside","oval","oven","over","own","owner","oxygen","oyster","ozone","pact","paddle","page","pair","palace","palm","panda","panel","panic","panther","paper","parade","parent","park","parrot","party","pass","patch","path","patient","patrol","pattern","pause","pave","payment","peace","peanut","pear","peasant","pelican","pen","penalty","pencil","people","pepper","perfect","permit","person","pet","phone","photo","phrase","physical","piano","picnic","picture","piece","pig","pigeon","pill","pilot","pink","pioneer","pipe","pistol","pitch","pizza","place","planet","plastic","plate","play","please","pledge","pluck","plug","plunge","poem","poet","point","polar","pole","police","pond","pony","pool","popular","portion","position","possible","post","potato","pottery","poverty","powder","power","practice","praise","predict","prefer","prepare","present","pretty","prevent","price","pride","primary","print","priority","prison","private","prize","problem","process","produce","profit","program","project","promote","proof","property","prosper","protect","proud","provide","public","pudding","pull","pulp","pulse","pumpkin","punch","pupil","puppy","purchase","purity","purpose","purse","push","put","puzzle","pyramid","quality","quantum","quarter","question","quick","quit","quiz","quote","rabbit","raccoon","race","rack","radar","radio","rail","rain","raise","rally","ramp","ranch","random","range","rapid","rare","rate","rather","raven","raw","razor","ready","real","reason","rebel","rebuild","recall","receive","recipe","record","recycle","reduce","reflect","reform","refuse","region","regret","regular","reject","relax","release","relief","rely","remain","remember","remind","remove","render","renew","rent","reopen","repair","repeat","replace","report","require","rescue","resemble","resist","resource","response","result","retire","retreat","return","reunion","reveal","review","reward","rhythm","rib","ribbon","rice","rich","ride","ridge","rifle","right","rigid","ring","riot","ripple","risk","ritual","rival","river","road","roast","robot","robust","rocket","romance","roof","rookie","room","rose","rotate","rough","round","route","royal","rubber","rude","rug","rule","run","runway","rural","sad","saddle","sadness","safe","sail","salad","salmon","salon","salt","salute","same","sample","sand","satisfy","satoshi","sauce","sausage","save","say","scale","scan","scare","scatter","scene","scheme","school","science","scissors","scorpion","scout","scrap","screen","script","scrub","sea","search","season","seat","second","secret","section","security","seed","seek","segment","select","sell","seminar","senior","sense","sentence","series","service","session","settle","setup","seven","shadow","shaft","shallow","share","shed","shell","sheriff","shield","shift","shine","ship","shiver","shock","shoe","shoot","shop","short","shoulder","shove","shrimp","shrug","shuffle","shy","sibling","sick","side","siege","sight","sign","silent","silk","silly","silver","similar","simple","since","sing","siren","sister","situate","six","size","skate","sketch","ski","skill","skin","skirt","skull","slab","slam","sleep","slender","slice","slide","slight","slim","slogan","slot","slow","slush","small","smart","smile","smoke","smooth","snack","snake","snap","sniff","snow","soap","soccer","social","sock","soda","soft","solar","soldier","solid","solution","solve","someone","song","soon","sorry","sort","soul","sound","soup","source","south","space","spare","spatial","spawn","speak","special","speed","spell","spend","sphere","spice","spider","spike","spin","spirit","split","spoil","sponsor","spoon","sport","spot","spray","spread","spring","spy","square","squeeze","squirrel","stable","stadium","staff","stage","stairs","stamp","stand","start","state","stay","steak","steel","stem","step","stereo","stick","still","sting","stock","stomach","stone","stool","story","stove","strategy","street","strike","strong","struggle","student","stuff","stumble","style","subject","submit","subway","success","such","sudden","suffer","sugar","suggest","suit","summer","sun","sunny","sunset","super","supply","supreme","sure","surface","surge","surprise","surround","survey","suspect","sustain","swallow","swamp","swap","swarm","swear","sweet","swift","swim","swing","switch","sword","symbol","symptom","syrup","system","table","tackle","tag","tail","talent","talk","tank","tape","target","task","taste","tattoo","taxi","teach","team","tell","ten","tenant","tennis","tent","term","test","text","thank","that","theme","then","theory","there","they","thing","this","thought","three","thrive","throw","thumb","thunder","ticket","tide","tiger","tilt","timber","time","tiny","tip","tired","tissue","title","toast","tobacco","today","toddler","toe","together","toilet","token","tomato","tomorrow","tone","tongue","tonight","tool","tooth","top","topic","topple","torch","tornado","tortoise","toss","total","tourist","toward","tower","town","toy","track","trade","traffic","tragic","train","transfer","trap","trash","travel","tray","treat","tree","trend","trial","tribe","trick","trigger","trim","trip","trophy","trouble","truck","true","truly","trumpet","trust","truth","try","tube","tuition","tumble","tuna","tunnel","turkey","turn","turtle","twelve","twenty","twice","twin","twist","two","ugly","umbrella","unable","unaware","uncle","uncover","under","undo","unfair","unfold","unhappy","uniform","unique","unit","universe","unknown","unlock","until","unusual","unveil","update","upgrade","uphold","upon","upper","upset","urban","urge","usage","use","used","useful","useless","usual","utility","vacant","vacuum","vague","valid","valley","valve","van","vanish","vapor","various","vast","vault","vehicle","velvet","vendor","venture","venue","verb","verify","version","very","vessel","veteran","viable","vibrant","vicious","victory","video","view","village","vintage","violin","virtual","virus","visa","visit","visual","vital","vivid","vocal","voice","void","volcano","volume","vote","voyage","wage","wagon","wait","walk","wall","walnut","want","warfare","warm","warrior","wash","wasp","waste","water","wave","way","wealth","weapon","wear","weasel","weather","web","wedding","weekend","weird","welcome","west","wet","whale","what","wheat","wheel","when","where","whip","whisper","wide","width","wife","wild","will","win","window","wine","wing","wink","winner","winter","wire","wisdom","wise","wish","witness","wolf","woman","wonder","wood","wool","word","work","world","worry","worth","wrap","wreck","wrestle","wrist","write","wrong","yard","year","yellow","you","young","youth","zebra","zero","zone","zoo"]
|
| 22 |
+
|
| 23 |
+
# ---------- Session State ----------
|
| 24 |
+
session_db: Dict[str, Dict[str, Any]] = {}
|
| 25 |
+
fib_state: Dict[str, 'FibTTL'] = {}
|
| 26 |
+
|
| 27 |
+
# ---------- Fibonacci TTL ----------
|
| 28 |
+
class FibTTL:
|
| 29 |
+
def __init__(self):
|
| 30 |
+
self.a, self.b = 0, 1
|
| 31 |
+
|
| 32 |
+
def next(self) -> int:
|
| 33 |
+
self.a, self.b = self.b, self.a + self.b
|
| 34 |
+
return max(30, min(self.a * 30, 300))
|
| 35 |
+
|
| 36 |
+
# ---------- Core Quantum & Crypto Functions ----------
|
| 37 |
+
class Core:
|
| 38 |
+
@staticmethod
|
| 39 |
+
def seed() -> bytes:
|
| 40 |
+
"""Generate quantum random seed using Cirq simulator"""
|
| 41 |
+
try:
|
| 42 |
+
q = [cirq.GridQubit(0, i) for i in range(256)]
|
| 43 |
+
c = cirq.Circuit(
|
| 44 |
+
cirq.H.on_each(*q),
|
| 45 |
+
[cirq.measure(qb, key=str(i)) for i, qb in enumerate(q)]
|
| 46 |
+
)
|
| 47 |
+
r = cirq.Simulator().run(c, repetitions=1)
|
| 48 |
+
bits = ''.join(str(r.measurements[str(i)][0][0]) for i in range(256))
|
| 49 |
+
return int(bits, 2).to_bytes(32, 'big')
|
| 50 |
+
except Exception as e:
|
| 51 |
+
# Fallback to cryptographic random
|
| 52 |
+
return os.urandom(32)
|
| 53 |
+
|
| 54 |
+
@staticmethod
|
| 55 |
+
def token(seed: bytes, ttl: int = 60) -> Tuple[str, int]:
|
| 56 |
+
"""Generate time-based token with TTL"""
|
| 57 |
+
now = int(time.time())
|
| 58 |
+
tw = now // ttl
|
| 59 |
+
tb = tw.to_bytes(8, 'big')
|
| 60 |
+
h = hashlib.sha256(seed + tb).digest()
|
| 61 |
+
tok = base64.b32encode(h[:5]).decode()[:8]
|
| 62 |
+
return tok, (tw + 1) * ttl - now
|
| 63 |
+
|
| 64 |
+
@staticmethod
|
| 65 |
+
def encrypt(data: Dict[str, Any], seed: bytes) -> Tuple[str, str]:
|
| 66 |
+
"""Encrypt data using AES-GCM"""
|
| 67 |
+
key = hashlib.sha256(seed).digest()
|
| 68 |
+
nonce = os.urandom(12)
|
| 69 |
+
aesgcm = AESGCM(key)
|
| 70 |
+
ct = aesgcm.encrypt(nonce, json.dumps(data).encode(), None)
|
| 71 |
+
return base64.b64encode(nonce + ct).decode(), hashlib.sha256(ct).hexdigest()
|
| 72 |
+
|
| 73 |
+
@staticmethod
|
| 74 |
+
def decrypt(enc: str, seed: bytes) -> Dict[str, Any]:
|
| 75 |
+
"""Decrypt data using AES-GCM"""
|
| 76 |
+
key = hashlib.sha256(seed).digest()
|
| 77 |
+
raw = base64.b64decode(enc)
|
| 78 |
+
aesgcm = AESGCM(key)
|
| 79 |
+
return json.loads(aesgcm.decrypt(raw[:12], raw[12:], None))
|
| 80 |
+
|
| 81 |
+
# ---------- Recovery Phrase ----------
|
| 82 |
+
def generate_recovery_phrase() -> str:
|
| 83 |
+
"""Generate 12-word BIP39 recovery phrase"""
|
| 84 |
+
return ' '.join(random.sample(BIP39, 12))
|
| 85 |
+
|
| 86 |
+
# ---------- IPFS (Pinata) ----------
|
| 87 |
+
class IPFS:
|
| 88 |
+
@staticmethod
|
| 89 |
+
def save(data: str) -> Optional[str]:
|
| 90 |
+
"""Save data to IPFS via Pinata"""
|
| 91 |
+
try:
|
| 92 |
+
r = requests.post(
|
| 93 |
+
"https://api.pinata.cloud/pinning/pinJSONToIPFS",
|
| 94 |
+
headers={
|
| 95 |
+
"pinata_api_key": PINATA_API_KEY,
|
| 96 |
+
"pinata_secret_api_key": PINATA_SECRET_KEY
|
| 97 |
+
},
|
| 98 |
+
json={"pinataContent": {"data": data}},
|
| 99 |
+
timeout=10
|
| 100 |
+
)
|
| 101 |
+
r.raise_for_status()
|
| 102 |
+
return r.json().get("IpfsHash")
|
| 103 |
+
except Exception as e:
|
| 104 |
+
print(f"IPFS save error: {e}")
|
| 105 |
+
return None
|
| 106 |
+
|
| 107 |
+
@staticmethod
|
| 108 |
+
def load(cid: str) -> Optional[Dict[str, Any]]:
|
| 109 |
+
"""Load data from IPFS via Pinata"""
|
| 110 |
+
try:
|
| 111 |
+
r = requests.get(f"https://gateway.pinata.cloud/ipfs/{cid}", timeout=10)
|
| 112 |
+
if r.status_code == 200:
|
| 113 |
+
return r.json().get("data")
|
| 114 |
+
except Exception as e:
|
| 115 |
+
print(f"IPFS load error: {e}")
|
| 116 |
+
return None
|
| 117 |
+
|
| 118 |
+
# ---------- Gradio App Functions ----------
|
| 119 |
+
def generate_quantum_seed() -> Tuple[str, str]:
|
| 120 |
+
"""Generate quantum random seed and display"""
|
| 121 |
+
seed = Core.seed()
|
| 122 |
+
seed_hex = seed.hex()
|
| 123 |
+
seed_preview = seed_hex[:32] + "..." if len(seed_hex) > 32 else seed_hex
|
| 124 |
+
return seed_hex, f"β
Seed Generated\n\nπ **Seed (Hex):** `{seed_preview}`\n\nβ‘ Generated using quantum simulation (Cirq)"
|
| 125 |
+
|
| 126 |
+
def generate_recovery_phrase_fn() -> str:
|
| 127 |
+
"""Generate and display recovery phrase"""
|
| 128 |
+
phrase = generate_recovery_phrase()
|
| 129 |
+
return f"π **Recovery Phrase:**\n\n`{phrase}`\n\nβ οΈ **SIMPAN FRASA INI!** Hanya dipapar sekali."
|
| 130 |
+
|
| 131 |
+
def register_user(username: str, seed_hex: str, progress=gr.Progress()) -> str:
|
| 132 |
+
"""Register a new user with encrypted data"""
|
| 133 |
+
if not username or not seed_hex:
|
| 134 |
+
return "β Sila masukkan username dan seed."
|
| 135 |
+
|
| 136 |
+
try:
|
| 137 |
+
seed = bytes.fromhex(seed_hex)
|
| 138 |
+
data = {
|
| 139 |
+
"username": username,
|
| 140 |
+
"registered_at": datetime.now().isoformat(),
|
| 141 |
+
"seed_hex": seed_hex
|
| 142 |
+
}
|
| 143 |
+
|
| 144 |
+
progress(0.3, desc="Encrypting data...")
|
| 145 |
+
enc, h = Core.encrypt(data, seed)
|
| 146 |
+
|
| 147 |
+
progress(0.6, desc="Saving to IPFS...")
|
| 148 |
+
cid = IPFS.save(enc)
|
| 149 |
+
|
| 150 |
+
if not cid:
|
| 151 |
+
return "β Gagal menyimpan ke IPFS. Cuba lagi."
|
| 152 |
+
|
| 153 |
+
phrase = generate_recovery_phrase()
|
| 154 |
+
session_id = hashlib.sha256(seed_hex.encode()).hexdigest()[:16]
|
| 155 |
+
session_db[session_id] = {
|
| 156 |
+
"cid": cid,
|
| 157 |
+
"seed_hex": seed_hex,
|
| 158 |
+
"hash": h,
|
| 159 |
+
"phrase": phrase,
|
| 160 |
+
"username": username
|
| 161 |
+
}
|
| 162 |
+
|
| 163 |
+
progress(1.0, desc="Registration complete!")
|
| 164 |
+
return f"""β
**Pendaftaran Berjaya!**
|
| 165 |
+
|
| 166 |
+
π **Session ID:** `{session_id}`
|
| 167 |
+
π¦ **CID:** `{cid}`
|
| 168 |
+
π **Hash:** `{h[:32]}...`
|
| 169 |
+
π **Frasa Pemulihan:** `{phrase}`
|
| 170 |
+
|
| 171 |
+
β οΈ **TULIS & SIMPAN FRASA INI!** Hanya dipapar sekali.
|
| 172 |
+
Gunakan Session ID untuk log masuk."""
|
| 173 |
+
except Exception as e:
|
| 174 |
+
return f"β Ralat: {str(e)}"
|
| 175 |
+
|
| 176 |
+
def generate_token(session_id: str) -> str:
|
| 177 |
+
"""Generate time-based token for session"""
|
| 178 |
+
if session_id not in session_db:
|
| 179 |
+
return "β Session tidak dijumpai. Sila daftar dahulu."
|
| 180 |
+
|
| 181 |
+
try:
|
| 182 |
+
session = session_db[session_id]
|
| 183 |
+
seed = bytes.fromhex(session["seed_hex"])
|
| 184 |
+
|
| 185 |
+
if session_id not in fib_state:
|
| 186 |
+
fib_state[session_id] = FibTTL()
|
| 187 |
+
|
| 188 |
+
ttl = fib_state[session_id].next()
|
| 189 |
+
tok, rem = Core.token(seed, ttl)
|
| 190 |
+
|
| 191 |
+
return f"""π **Token:** `{tok}`
|
| 192 |
+
|
| 193 |
+
β³ **Masa Sah:** {rem}s
|
| 194 |
+
π **Fibonacci TTL:** {ttl}s
|
| 195 |
+
|
| 196 |
+
Token akan berubah setiap {ttl} saat."""
|
| 197 |
+
except Exception as e:
|
| 198 |
+
return f"β Ralat: {str(e)}"
|
| 199 |
+
|
| 200 |
+
def encrypt_data(data: str, seed_hex: str) -> str:
|
| 201 |
+
"""Encrypt user data"""
|
| 202 |
+
if not data or not seed_hex:
|
| 203 |
+
return "β Sila masukkan data dan seed."
|
| 204 |
+
|
| 205 |
+
try:
|
| 206 |
+
seed = bytes.fromhex(seed_hex)
|
| 207 |
+
enc, h = Core.encrypt({"data": data}, seed)
|
| 208 |
+
return f"""β
**Data Diencrypt!**
|
| 209 |
+
|
| 210 |
+
π **Encrypted:** `{enc[:50]}...`
|
| 211 |
+
π **Hash:** `{h}`
|
| 212 |
+
|
| 213 |
+
Salin encrypted data untuk disimpan."""
|
| 214 |
+
except Exception as e:
|
| 215 |
+
return f"β Ralat: {str(e)}"
|
| 216 |
+
|
| 217 |
+
def decrypt_data(encrypted: str, seed_hex: str) -> str:
|
| 218 |
+
"""Decrypt user data"""
|
| 219 |
+
if not encrypted or not seed_hex:
|
| 220 |
+
return "β Sila masukkan encrypted data dan seed."
|
| 221 |
+
|
| 222 |
+
try:
|
| 223 |
+
seed = bytes.fromhex(seed_hex)
|
| 224 |
+
decrypted = Core.decrypt(encrypted, seed)
|
| 225 |
+
return f"""β
**Data Didecrypt!**
|
| 226 |
+
|
| 227 |
+
π **Data:** `{json.dumps(decrypted, indent=2)}`"""
|
| 228 |
+
except Exception as e:
|
| 229 |
+
return f"β Ralat decrypt: {str(e)}"
|
| 230 |
+
|
| 231 |
+
def load_from_ipfs(cid: str) -> str:
|
| 232 |
+
"""Load data from IPFS"""
|
| 233 |
+
if not cid:
|
| 234 |
+
return "β Sila masukkan CID."
|
| 235 |
+
|
| 236 |
+
try:
|
| 237 |
+
data = IPFS.load(cid)
|
| 238 |
+
if data:
|
| 239 |
+
return f"""β
**Data Berjaya Dimuatkan!**
|
| 240 |
+
|
| 241 |
+
π¦ **CID:** `{cid}`
|
| 242 |
+
π **Data:** `{json.dumps(data, indent=2)}`"""
|
| 243 |
+
else:
|
| 244 |
+
return "β Gagal memuatkan data dari IPFS."
|
| 245 |
+
except Exception as e:
|
| 246 |
+
return f"β Ralat: {str(e)}"
|
| 247 |
+
|
| 248 |
+
def verify_recovery_phrase(phrase: str, session_id: str) -> str:
|
| 249 |
+
"""Verify recovery phrase matches session"""
|
| 250 |
+
if session_id not in session_db:
|
| 251 |
+
return "β Session tidak dijumpai."
|
| 252 |
+
|
| 253 |
+
session = session_db[session_id]
|
| 254 |
+
if phrase.strip() == session["phrase"]:
|
| 255 |
+
return f"""β
**Frasa Pemulihan Sah!**
|
| 256 |
+
|
| 257 |
+
π€ **Username:** `{session['username']}`
|
| 258 |
+
π¦ **CID:** `{session['cid']}`
|
| 259 |
+
π **Seed:** `{session['seed_hex'][:32]}...`
|
| 260 |
+
|
| 261 |
+
Anda boleh memulihkan akses anda."""
|
| 262 |
+
else:
|
| 263 |
+
return "β Frasa pemulihan tidak sepadan."
|
| 264 |
+
|
| 265 |
+
# ---------- Custom Theme ----------
|
| 266 |
+
custom_theme = gr.themes.Soft(
|
| 267 |
+
primary_hue="indigo",
|
| 268 |
+
secondary_hue="purple",
|
| 269 |
+
neutral_hue="slate",
|
| 270 |
+
font=gr.themes.GoogleFont("Inter"),
|
| 271 |
+
text_size="lg",
|
| 272 |
+
spacing_size="lg",
|
| 273 |
+
radius_size="md"
|
| 274 |
+
).set(
|
| 275 |
+
button_primary_background_fill="*primary_600",
|
| 276 |
+
button_primary_background_fill_hover="*primary_700",
|
| 277 |
+
block_title_text_weight="600",
|
| 278 |
+
body_text_size="md",
|
| 279 |
+
)
|
| 280 |
+
|
| 281 |
+
# ---------- Gradio Interface (GRADIO 6 SYNTAX) ----------
|
| 282 |
+
# π¨ CRITICAL: gr.Blocks() has NO parameters in Gradio 6!
|
| 283 |
+
with gr.Blocks() as demo:
|
| 284 |
+
gr.Markdown("""
|
| 285 |
+
# π Hadamard Quantum Vault
|
| 286 |
+
|
| 287 |
+
Sistem keselamatan berasaskan quantum dengan enkripsi AES-GCM dan storan IPFS.
|
| 288 |
+
|
| 289 |
+
<div style="text-align: center; margin: 20px 0;">
|
| 290 |
+
<a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" style="text-decoration: none;">
|
| 291 |
+
<span style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 8px 16px; border-radius: 20px; font-weight: bold;">
|
| 292 |
+
Built with anycoder π
|
| 293 |
+
</span>
|
| 294 |
+
</a>
|
| 295 |
+
</div>
|
| 296 |
+
""")
|
| 297 |
+
|
| 298 |
+
with gr.Tabs():
|
| 299 |
+
# Tab 1: Quantum Seed Generation
|
| 300 |
+
with gr.TabItem("π Quantum Seed", id=1):
|
| 301 |
+
gr.Markdown("### Generate seed kuantum rawak menggunakan simulator Cirq")
|
| 302 |
+
with gr.Row():
|
| 303 |
+
with gr.Column(scale=1):
|
| 304 |
+
seed_btn = gr.Button("π² Generate Quantum Seed", variant="primary", size="lg")
|
| 305 |
+
with gr.Column(scale=2):
|
| 306 |
+
seed_output = gr.Textbox(label="Quantum Seed (Hex)", lines=3, interactive=False)
|
| 307 |
+
seed_info = gr.Markdown()
|
| 308 |
+
|
| 309 |
+
seed_btn.click(generate_quantum_seed, outputs=[seed_output, seed_info])
|
| 310 |
+
|
| 311 |
+
# Tab 2: Recovery Phrase
|
| 312 |
+
with gr.TabItem("π Recovery Phrase", id=2):
|
| 313 |
+
gr.Markdown("### Jana frasa pemulihan 12-kata BIP39")
|
| 314 |
+
with gr.Row():
|
| 315 |
+
with gr.Column(scale=1):
|
| 316 |
+
phrase_btn = gr.Button("π Generate Phrase", variant="primary", size="lg")
|
| 317 |
+
with gr.Column(scale=2):
|
| 318 |
+
phrase_output = gr.Markdown()
|
| 319 |
+
|
| 320 |
+
phrase_btn.click(generate_recovery_phrase_fn, outputs=phrase_output)
|
| 321 |
+
|
| 322 |
+
# Tab 3: User Registration
|
| 323 |
+
with gr.TabItem("π€ Register User", id=3):
|
| 324 |
+
gr.Markdown("### Daftarkan pengguna baru dengan data terenkripsi")
|
| 325 |
+
with gr.Row():
|
| 326 |
+
with gr.Column():
|
| 327 |
+
reg_username = gr.Textbox(label="Username", placeholder="Masukkan username")
|
| 328 |
+
reg_seed = gr.Textbox(label="Seed (Hex)", placeholder="Paste seed dari tab Quantum Seed", lines=2)
|
| 329 |
+
reg_btn = gr.Button("π Register", variant="primary", size="lg")
|
| 330 |
+
with gr.Column():
|
| 331 |
+
reg_output = gr.Markdown()
|
| 332 |
+
|
| 333 |
+
reg_btn.click(register_user, inputs=[reg_username, reg_seed], outputs=reg_output)
|
| 334 |
+
|
| 335 |
+
# Tab 4: Token Generation
|
| 336 |
+
with gr.TabItem("π« Generate Token", id=4):
|
| 337 |
+
gr.Markdown("### Jana token berasaskan masa dengan Fibonacci TTL")
|
| 338 |
+
with gr.Row():
|
| 339 |
+
with gr.Column():
|
| 340 |
+
token_session = gr.Textbox(label="Session ID", placeholder="Masukkan Session ID dari pendaftaran")
|
| 341 |
+
token_btn = gr.Button("π Generate Token", variant="primary", size="lg")
|
| 342 |
+
with gr.Column():
|
| 343 |
+
token_output = gr.Markdown()
|
| 344 |
+
|
| 345 |
+
token_btn.click(generate_token, inputs=token_session, outputs=token_output)
|
| 346 |
+
|
| 347 |
+
# Tab 5: Encrypt/Decrypt
|
| 348 |
+
with gr.TabItem("π Encrypt/Decrypt", id=5):
|
| 349 |
+
with gr.Row():
|
| 350 |
+
with gr.Column():
|
| 351 |
+
gr.Markdown("#### Encrypt Data")
|
| 352 |
+
enc_data = gr.Textbox(label="Data to Encrypt", lines=3, placeholder="Masukkan data untuk diencrypt")
|
| 353 |
+
enc_seed = gr.Textbox(label="Seed (Hex)", lines=2, placeholder="Seed untuk encryption")
|
| 354 |
+
enc_btn = gr.Button("π Encrypt", variant="primary")
|
| 355 |
+
enc_output = gr.Markdown()
|
| 356 |
+
|
| 357 |
+
enc_btn.click(encrypt_data, inputs=[enc_data, enc_seed], outputs=enc_output)
|
| 358 |
+
|
| 359 |
+
with gr.Column():
|
| 360 |
+
gr.Markdown("#### Decrypt Data")
|
| 361 |
+
dec_data = gr.Textbox(label="Encrypted Data", lines=3, placeholder="Paste encrypted data")
|
| 362 |
+
dec_seed = gr.Textbox(label="Seed (Hex)", lines=2, placeholder="Seed yang sama untuk decryption")
|
| 363 |
+
dec_btn = gr.Button("π Decrypt", variant="secondary")
|
| 364 |
+
dec_output = gr.Markdown()
|
| 365 |
+
|
| 366 |
+
dec_btn.click(decrypt_data, inputs=[dec_data, dec_seed], outputs=dec_output)
|
| 367 |
+
|
| 368 |
+
# Tab 6: IPFS Storage
|
| 369 |
+
with gr.TabItem("βοΈ IPFS Storage", id=6):
|
| 370 |
+
gr.Markdown("### Muat turun data dari IPFS menggunakan CID")
|
| 371 |
+
with gr.Row():
|
| 372 |
+
with gr.Column():
|
| 373 |
+
ipfs_cid = gr.Textbox(label="IPFS CID", placeholder="Masukkan CID dari Pinata/IPFS")
|
| 374 |
+
ipfs_btn = gr.Button("π₯ Load from IPFS", variant="primary", size="lg")
|
| 375 |
+
with gr.Column():
|
| 376 |
+
ipfs_output = gr.Markdown()
|
| 377 |
+
|
| 378 |
+
ipfs_btn.click(load_from_ipfs, inputs=ipfs_cid, outputs=ipfs_output)
|
| 379 |
+
|
| 380 |
+
# Tab 7: Verify Recovery
|
| 381 |
+
with gr.TabItem("β
Verify Phrase", id=7):
|
| 382 |
+
gr.Markdown("### Sahkan frasa pemulihan untuk memulihkan akses")
|
| 383 |
+
with gr.Row():
|
| 384 |
+
with gr.Column():
|
| 385 |
+
verify_session = gr.Textbox(label="Session ID", placeholder="Masukkan Session ID")
|
| 386 |
+
verify_phrase = gr.Textbox(label="Recovery Phrase", lines=2, placeholder="Paste frasa pemulihan 12-kata")
|
| 387 |
+
verify_btn = gr.Button("β
Verify", variant="primary", size="lg")
|
| 388 |
+
with gr.Column():
|
| 389 |
+
verify_output = gr.Markdown()
|
| 390 |
+
|
| 391 |
+
verify_btn.click(verify_recovery_phrase, inputs=[verify_phrase, verify_session], outputs=verify_output)
|
| 392 |
+
|
| 393 |
+
# Footer
|
| 394 |
+
gr.Markdown("""
|
| 395 |
+
---
|
| 396 |
+
### π Security Notes
|
| 397 |
+
- **Quantum Seed**: Generated using Cirq quantum simulator (256 qubits)
|
| 398 |
+
- **Encryption**: AES-GCM with 256-bit keys
|
| 399 |
+
- **Storage**: IPFS via Pinata (decentralized)
|
| 400 |
+
- **Recovery**: BIP39 12-word phrase
|
| 401 |
+
|
| 402 |
+
β οΈ **Simpan seed dan recovery phrase anda dengan selamat!**
|
| 403 |
+
""")
|
| 404 |
+
|
| 405 |
+
# ---------- Launch (GRADIO 6 SYNTAX) ----------
|
| 406 |
+
# π¨ CRITICAL: ALL app parameters go in demo.launch() for Gradio 6!
|
| 407 |
+
if __name__ == "__main__":
|
| 408 |
+
demo.launch(
|
| 409 |
+
theme=custom_theme,
|
| 410 |
+
footer_links=[
|
| 411 |
+
{"label": "Built with anycoder", "url": "https://huggingface.co/spaces/akhaliq/anycoder"},
|
| 412 |
+
{"label": "Gradio Docs", "url": "https://gradio.app/docs"},
|
| 413 |
+
{"label": "Cirq Documentation", "url": "https://quantumai.google/cirq"}
|
| 414 |
+
]
|
| 415 |
+
)
|