from Crypto.Util.number import * try: gcd except NameError: from math import gcd
defgen_prime(nbits: int, gamma: float): g = getPrime(int(nbits * gamma)) alpha = 0.5 - gamma whileTrue: a = getRandomNBitInteger(int(alpha * nbits)) p = 2 * g * a + 1 if isPrime(p): b = getRandomNBitInteger(int(alpha * nbits)) q = 2 * g * b + 1 h = 2 * g * a * b + a + b whilenot isPrime(q) or isPrime(h) or gcd(a, b) != 1: b = getRandomNBitInteger(int(alpha * nbits)) h = 2 * g * a * b + a + b q = 2 * g * b + 1 return p, q print(gen_prime(512, 0.48))
from Crypto.Util.number import * from gmpy2 import invert
f = lambda x,n: (pow(x, n - 1, n) + 3) % n defphllard_rho(n): i = 1 whileTrue: a = getRandomRange(2, n) b = f(a, n) j = 1 whileTrue: p = GCD(abs(a - b), n) if p == n: break elif p > 1: return (p, n // p) else: a = f(a, n) b = f(f(b, n), n) j += 1 i += 1
from Crypto.Util.number import * from flag import flag import gmpy2
defgen_prime(nbits, gamma): g = getPrime(int(nbits * gamma)) #491 alpha = 0.5 - gamma #0.02 whileTrue: a = getRandomNBitInteger(int(alpha * nbits)) #20 p = 2 * g * a + 1 if isPrime(p): b = getRandomNBitInteger(int(alpha * nbits)) #20 q = 2 * g * b + 1 h = 2 * g * a * b + a + b whilenot isPrime(q) or isPrime(h) or gmpy2.gcd(a, b) != 1: b = getRandomNBitInteger(int(alpha * nbits)) q = 2 * g * b + 1 return p, q
defencrypt(nbits, gamma): p, q = gen_prime(nbits, gamma) n = p * q e = getPrime(16) while gmpy2.gcd(e, gmpy2.lcm(p-1,q-1)) != 1: e = getPrime(16) m = bytes_to_long(flag) c = pow(m, e, n) return n, e, c
n, e, c = encrypt(1024, 0.48) print'n =', n print'e =', e print'c =', c
# n = 84236796025318186855187782611491334781897277899439717384242559751095347166978304126358295609924321812851255222430530001043539925782811895605398187299748256080526691975084042025794113521587064616352833904856626744098904922117855866813505228134381046907659080078950018430266048447119221001098505107823645953039 # e = 58337 # c = 13646200911032594651110040891135783560995665642049282201695300382255436792102048169200570930229947213493204600006876822744757042959653203573780257603577712302687497959686258542388622714078571068849217323703865310256200818493894194213812410547780002879351619924848073893321472704218227047519748394961963394668
from Crypto.Util.number import * from gmpy2 import invert
f = lambda x,n: (pow(x, n - 1, n) + 3) % n defphllard_rho(n): i = 1 whileTrue: a = getRandomRange(2, n) b = f(a, n) j = 1 whileTrue: p = GCD(abs(a - b), n) if p == n: break elif p > 1: return (p, n // p) else: a = f(a, n) b = f(f(b, n), n) j += 1 i += 1
n = 84236796025318186855187782611491334781897277899439717384242559751095347166978304126358295609924321812851255222430530001043539925782811895605398187299748256080526691975084042025794113521587064616352833904856626744098904922117855866813505228134381046907659080078950018430266048447119221001098505107823645953039 p,q = phllard_rho(n) print(p) #9983140483800634632426126985832058062766650402234684899412786169759602188949733747138853010482968306554808689182393249326088351886439191015684338347893201 print(q) #8437905502983445042677582637893534375137565614989838462475696727313788501904161403475771835934720130340799646782932619714906025013322551788559197469878239
当的γ值很小的时候
一般在0.10左右,可以尝试使用yafu分解2N−1,或者使用上面的板子
已知a、b的值
这时候关于n的等式就只有g一个未知量,直接roots来解就可以了
1 2 3 4 5 6 7 8 9 10 11 12
a = b = N = P.<g> = ZZ[] #因为这边我们只需要整数解,所以限制在整数环上面就行了 f = 4 * a * b * g ^ 2 + 2 * (a + b) * g - N + 1 g = f.roots() if g: g = g[0][0] p = 2 * g * a + 1 q = 2 * g * b + 1 print(g) assert p * q == N
f1 = a + b - g f2 = 4 * g ^ 2 * a * b + 2 * g * a + 2 * g * b + 1 - N f = resultant(f1, f2, b) f #-4*a^2*g^2 + 4*a*g^3 + 2*g^2 - N + 1
然后这个然后是在模N下是解不出来的,但是毕竟只有一个变量,我们直接在ZZ下解就行了
1 2 3 4 5 6 7 8 9 10 11
g = N = R.<a> = ZZ[] f = -4*a^2*g^2 + 4*a*g^3 + 2*g^2 - N + 1 res = f.roots() if res: a, b = res[0][0], res[1][0] p = 2 * g * a + 1 q = 2 * g * b + 1 assert p * q == N
f1 = a + b - a_b f2 = 4 * g ^ 2 * a * b + 2 * g * a + 2 * g * b + 1 - N f = resultant(f1, f2, b) f #-4*a^2*g^2 + 4*a*g^2*a_b + 2*g*a_b - N + 1
1 2 3 4 5 6 7 8 9 10 11 12
g = N = a_b = (N-1) // 2 * g % g R.<a> = ZZ[] f = -4*a^2*g^2 + 4*a*g^2*a_b + 2*g*a_b - N + 1 res = f.roots() if res: a, b = res[0][0], res[1][0] p = 2 * g * a + 1 q = 2 * g * b + 1 assert p * q == N
M = (N - 1) // (2 * g) u = M // (2 * g) v = M - 2 * g * u GF = Zmod(N) x = GF.random_element() y = x ^ (2 * g) # c的范围大概与N^(0.5-2*gamma)很接近 c = bsgs(y, y ^ u, (2**(cbits-1), 2**(cbits+1)), operation='*') #(a, b, bounds, operation='*', identity=None, inverse=None, op=None) ab = u - c apb = v + 2 * g * c P.<x> = ZZ[] f = x ^ 2 - apb * x + ab a = f.roots() if a: a, b = a[0][0], a[1][0] p = 2 * g * a + 1 q = 2 * g * b + 1 assert p * q == N
M = (N - 1) // (2 * g) u = M // (2 * g) v = M - 2 * g * u GF = Zmod(N) x = GF.random_element() y = x ^ (2 * g) # c的范围大概与N^(0.5-2*gamma)很接近 c = bsgs(y, y ^ u, (2**(cbits-1), 2**(cbits+1)), operation='*') #(a, b, bounds, operation='*', identity=None, inverse=None, op=None) ab = u - c apb = v + 2 * g * c P.<x> = ZZ[] f = x ^ 2 - apb * x + ab a = f.roots() if a: a, b = a[0][0], a[1][0] p = 2 * g * a + 1 q = 2 * g * b + 1 assert p * q == N