import os from Crypto.Util.number import getPrime as get_prime from Crypto.Util.number import isPrime as is_prime import secrets import hashlib
# Computes the inverse of a mod prime p definverse(a, p): returnpow(a, p-2, p)
defhash(m): h = hashlib.sha256(m).digest() returnint.from_bytes(h, 'big')
defgenerate_parameters(): # FIPS 186-4 specifies that p and q can be of (2048, 256) bits whileTrue: q = get_prime(256) r = secrets.randbits(2048-256) p = r*q + 1 if p.bit_length() != 2048: continue ifnot is_prime(p): continue break h = 1 whileTrue: h += 1 g = pow(h, (p-1)//q, p) if g == 1: continue break
return p, q, g
defsign(params, x, m): p, q, g = params
k = secrets.randbelow(q) r = pow(g, k, p) % q s = inverse(k, q) * (hash(m) + x*r) % q
return (r, s)
defverify(params, y, m, sig): p, q, g = params r, s = sig
assert0 < r < p assert0 < s < p
w = inverse(s, q) u1 = hash(m) * w % q u2 = r * w % q v = pow(g, u1, p) * pow(y, u2, p) % p % q assert v == r
defmain(): # The parameters were generated by generate_parameters(), which will take some time to generate. # With that reason, we will use a fixed one instead of a random one. p = 17484281359996796703320753329289113133879315487679543624741105110874484027222384531803606958810995970161525595158267517181794414300756262340838882222415769778596720783078367872913954804658072233160036557319401158197234539657653635114116129319712841746177858547689703847179830876938850791424742190500438426350633498257950965188623233005750174576134802300600490139756306854032656842920490457629968890761814183283863329460516285392831741363925618264196019954486854731951282830652117210758060426483125525221398218382779387124491329788662015827601101640859700613929375036792053877746675842421482667089024073397901135900307 q = 113298192013516195145250438847099037276290008150762924677454979772524099733149 g = 2240914810379680126339108531401169275595161144670883986559069211999660898639987625873945546061830376966978596453328760234030133281772778843957617704660733666090807506024220142764237508766050356212712228439682713526208998745633642827205871276203625236122884797705545378063530457025121059332887929777555045770309256917282489323413372739717067924463128766609878574952525765509768641958927377639405729673058327662319958260422021309804322093360414034030331866591802559201326691178841972572277227570498592419367302032451643108376739154217604459747574970395332109358575481017157712896404133971465638098583730000464599930248
deffind(x): iflen(x) == 256: xx = int(x, 2) if (pow(a, I, b) * pow(xx, 4, b) - n) % b == 0: out.append(xx) return else: for i in"01": xx = i + x bb = 2 ** len(x) xxx = int(xx, 2) if (pow(a, I, bb) * pow(xxx, 4, bb) - n) % bb == 0: find(xx)
out = [] b = 2**256 a = 102197201962123846389438942955101245465045811321520032783251514372432272871077 n = 712650313276602240132329097304430048400352751513310575526412992129597422070848111072491134888258819603174150809317988369755331029009864211216547294646211646094933573124257136163629116984386416188859789467395164897001085191528084740453428500956450177548977865861466055171717564208692444769495508512419622780024874941844495178742341131675818700155796280310646897103229083027529919187454771613414875490462993045875936234591157744167214046734190302287427367403568860249349359776931200150301621481939428066984857258770478004853926288162003818241246878159630318266155498887714140614580751646422502723648142074111613225912644502226694307736726087673647398291980857229829977354067820423709011783907277562489549103977052076140881547728240425069463175586173317054911517453708001448687312406872942899280723472709421452062317503252258181984837591194705354256671714708896675155493168030996749797654707148117051477506855802867089687545890519363621855230477269747205380531049996041867129632051572747028441506474146062043427303954298727328531350438208765938027973006421501568307421856483699068172998763428694958905673708416275143602068221058898394079378423785058886143156065469790907727616640696078658243794470631540358286862899496224884600294835441 e = 65537 c = 445308155915029567991204642441037106636274278969323594266962964897048528466773947276913391974222302661172087064465526779062356615268434642959161607080766074334140739062421641878296527210809334178619685030176261525389226557543594953035919061416292966585184462770190073132725325830890587610808224156896611989260754435566640011008330800266408350415234832430226789140062590779004940578475055195767146347394381212157930691103929079825296986828415158506003438261121628407171546274414046568037336522095223978532053246031668840069046046390952201058199981492454288495640857942797704964843287034359460079316661425483842570190113998195387780579545809621808801626313837113473885818945052873823360056317079785841069224993435527933283918571286444280017102781865312454024328849395335083566145607543834607504822081522250923714391873652357185101163374950977150829214936039230387625706376713934778873385375582488086205462961139042991664546797362021066081938999660281537596860879414252495949608351649066648594254272314188241185715920283526637402373027396529855631498571685297193020517033784357794223831020791070397249992230576960345185544552280142788704673413055403847038488791910041421887897364099871208624646292906015164161354890370666964030412257423 I = 0 find("") P = [] for x in out: for i inrange(-4000, 4000): p = pow(a, i, b) * x % b * b**3 + pow(a, i + 1, b) * x % b * b**2 + pow(a, i + 2, b) * x % b * b**1 + pow(a, i + 3, b) * x % b if n%p == 0: P.append(p) P = set(P) print(len(P)) print(P) phi = 1 for p in P: phi *= p-1 d=inverse(e,phi) print(long_to_bytes(pow(c,d,n)))
b = 2**256 c = 14258939715516539295587731120991968901228171455016001595761489750577784177213 n = 279784521303926518544200383491171400996467006054806060652945044514173580730320793076951350168517896308345078513333979433742090849938580604359515861344088875721354836410510396140219655796215325682295239294661185563708496490830500773420871847769568879274978173218440545663363350310752698066412613793738234395676975963986090446949443295350235071286869321557833967521199446244573020803085515110891641843096725596572980675877230459500589604078432572911282759481893882548258867802789628543364574694501159808895930747113406016718685856976531978713324829507636743778130758650283045513372598798114943752532619142439604369129493324057181519512588183783756314385380800844831034863151900295735342816476791991454383732133474515109758087482912794282007801160780475284011802960270750792620686906175026995623082009841402872948756740311519047998978234628057595438481437871594714428834059691733188294695393205472914443179153321670750219104306769911019089432918102588905808629421158434486927928786793524017503900505368724824170796339023214910404096208544407500008089429770878575702088992309354303731919302687039737672125268143820658069899761163750521000478474705014645224845757836226858836333259628284972467671764606702417658922805838428375959908059533 """ from tqdm import trange PR.<x> = PolynomialRing(Zmod(n)) for i in trange(1000): k = 4 * i t = k * c % b for k1 in range(2): for k2 in range(2): for k3 in range(2): for k4 in range(2): for k5 in range(2): for k6 in range(2): for k7 in range(2): pp = x * b ^ 3 + (x + c - k1 * b) * b ^ 2 + (x + 2 * c - (k1 + k2) * b) * b + x + 3 * c - (k1 + k2 + k3) * b qq = (x + t - k4 * b) * b ^ 3 + (x + t + c - (k4 + k5) * b) * b ^ 2 + (x + t + 2 * c - (k4 + k5 + k6) * b) * b + x + t + 3 * c - (k4 + k5 + k6 + k7) * b f = pp * qq roots = f.monic().small_roots(X=2 ^ 256, beta=0.25) if roots: print(roots) """ x = 84705119374453985280579495397595127888476080054094351532697352435930792929010 p = x % b * b**3 + (x + c) % b * b**2 + (x + 2 * c) % b * b + (x + 3 * c) % b enc = 12668023009781840908542456747150790958366008947388222673139950309896560492008423201703814113959062916216738813414905779255815616125482715748800637882572776464413794672305560913420843604427904075596817771292191713968187201485479797042112384390953800170012145372635694385419895184449315436204936393181245447065007450494691263361925589404791904565458416407877820052394996905208559706702586674504665164085593562932792149402776674399837342851449263354042894145700586851308674806581185881411576045932596814585050689676622481653401541955765009732517013919996864475158687111703292317464104677422251199063539026204584634157266215824371162154934075299210675220082034930924899581928745732959112210135371763739653442724659470938281648056607023621212384635978368358089470066114660978000389704285586405309891824263306072117253963803228130111794609335559502199299483268104278641029669532263556375348912538425414244341532656162870453118645106346455731193356791582571147804331894783849241501307040707035938949680381788534081674899875606974239354654393310878542209938345878740320797711262798440736790479007006147569066845667894663218494368548456732889916013895067014484182872120996578247736683746861794081478555452926231507488557048374863197550101866 e = 65537 d = inverse(e, p - 1) print(long_to_bytes(pow(enc, d, p)))
defget_prime(lcg, bits): whileTrue: p = 0 for i inrange(bits//lcg.bits): p <<= lcg.bits p |= lcg.next()
if p.bit_length() != bits: continue ifnot isPrime(p): continue
return p defget_number(lcg, bits): whileTrue: p = 0 for i inrange(bits//lcg.bits): p <<= lcg.bits p |= lcg.next() return p M = 3200 a = 14766004292360945258404852367497617471774948936126805425073927394403062559771 c = 101392444572529008969348961056906071660419768871029068095780498478077435335658 m = 2**128 n = 310104949044058363811425892282439667555795850923698164575500719920877363952490328278993741848588550303907803963138208625777769116407165079299045658359072735954939955634899149028890186203432587177185672614983999894171325785452784795686085757918290966774324125319406224747711723917236527562556229579589022628862590296281590323788478820477333016394079937231878378358046269624402362566235154381484471820688582120004595351405438024178098190005187895688879764539037795309008703147966413618274215850034115978270168263624156747737483336047033398686990065931568589053366201551840168657333564635190953575770912434947264202860664609208924668470174089395139643640441218757659152083626042918967413234744394606549606305861281752161107561439760204185976944782327736965087510398008449771008025699947582049442588729371212204993669594933838721600502189158688622194652824336960901728311819450912079584032482610919375366829986623070788751982011540521220055895553821778224253746970625666841786339189340344498152279172317609743104777470108401770109956350920020610131660906732383196598286142112787914912796448301345111823730145040316068582039211121377301361760688564938322941885358577303167411970251703604232966219027983536858119778300500933101751641899457 e = 65537 enc = 103062216319994633883021726707255505833894115982244229797744500400724941059411346264133479322957473182662752018633592486294774530211270693527482730004815628242002327808204776228223444383519632042858531074466552102288702530352869324049976713089889252600765238196110451324303956172732401402047005544975223308718486936799382134071405038584109821524691964342940757473561547043393942877521141027936710682878315017107714350048208655766169663561363722598270709129397838087810818396682268983758680728353233325680608113581239966748966828100455121487936700949018790286804701500925964419202040562160087415752569883786048654250026952720505649274955681447219364518875892085854376617187428517680579374255991868541726338897567149638047885985817814723274557132684796698662679779677729590702208805883768828626340945484760552452520907126473183457061321026569739763527385628295340908066618403473190885048961117252304808518351740671498261396384433967551138018727839531240932197016466713851341150888734655103395641340466366445201973820121462512449662479632578237405866465926851495594436176622348441495580476338358402531879195673909374090632193981789951544889982768669254824649367936539308980191669227919352771464458152027996758074065744620552247585183945 lcg = LCG(bits=256, seed=1, a=a, c=c) ps = [get_number(lcg, 1024) % m for _ inrange(M)]
mitm = {} defMITM(): for x1 in trange(M): for x2 inrange(x1): mitm[ps[x1] * ps[x2] % m] = (x1, x2) for x3 in trange(M): for x4 inrange(x1): u = n * gmpy2.invert(ps[x3] * ps[x4], m) % m if u in mitm: return (*mitm[u], x3, x4) X = MITM() print(X) X = [4 * (i + 1) for i in X] mod = 2**256 R.<s> = Zmod(mod)[] defgen(x): returnpow(a, x, mod) * s + c * sum(pow(a, i, mod) for i inrange(x)) f = prod(gen(x) for x in X) - n seeds = [int(i) for i in f.roots(multiplicities=False)] for seed in seeds: if seed % m == 1: lcg = LCG(bits=256, seed=seed, a=a, c=c) ps = [get_prime(lcg, bits=1024) for _ inrange(4)] if prod(ps) == n: d = inverse(e, prod(p - 1for p in ps)) print(long_to_bytes(pow(enc, d, n)))