#output:a*(x**(times)) , a是多项式 definner_mul(a,times): if times == 0: return a elif a > 127: a = a<<1 a = a % 256 a = a^27 else: a = a<<1 times = times - 1 return inner_mul(a,times)
#input: a,b ∈ GF(2**8) #output: a*b defmul(a,b): result = 0 bb = '{:08b}'.format(b) bb = bb[::-1] for i inrange(8): if(bb[i] == '1'): result = result^inner_mul(a,i) else: pass return result
temp = [] for i inrange(8): temp.append(int(inbit[i])) res = [0,0,0,0,0,0,0,0] #res = temp c = [1,1,0,0,0,1,1,0] result = 0 for i inrange(8): res[i] = temp[i]^temp[(i+4)%8]^temp[(i+5)%8]^temp[(i+6)%8]^temp[(i+7)%8]^c[i] result += res[i]*(2**i)
returnhex(result)
defcreat_sbox(): box = [] sbox = 0x0 for i inrange(256): sbox=substitution(xgcd(283,i)) #283代表不可约多项式:x**8+x**4+x**3+x+1 box.append(sbox) for j inrange(256): print(box[j],end=' ') if (j+1)%16==0: print('\n')
//output: c = m^2e mod n voidcreat_c_new(mpz_t c){ mpz_t x,n; mpz_inits(x,n,NULL); mpz_set_str(x,c_star_s,10); //x = c_star = m^e mod n mpz_set_str(n,N_str,10); mpz_powm_ui(c,x,2,n); }
intmain(){ mpz_t c,y; char *y_str; mpz_inits(c,y,NULL); creat_c_new(c); y_str = dec(c); //output: y = m^{2ed} mod n = m^2 mod n cout<<"m**2:"<<y_str<<endl<<"m:"; mpz_set_str(y,y_str,10); mpz_root(y,y,2); mpz_out_str(stdout,10,y); return0; }
作业五:RSA破解
Alice decides to use RSA with the public key N = 1889570071. In order to guard against transmission errors, Alice has Bob encrypt his message twice, once using the encryption exponent e1 = 1021763679 and once using the encryption exponent e2 = 519424709. Eve intercepts the two encrypted messages
c1 = 1244183534 and c2 = 732959706. Assuming that Eve also knows N and the two encryption exponents e1 and e2. Please help Eve recover Bob’s plaintext without finding a factorization of N.
,
N =
188115669939527035644766943794256836704505079895306601119938518634078379404429524926183546093986493443422022468844644307633083886388295943602507953702360632321739073592477683222131866451975315695813478098524853358977564134499058448438525811837376172990710150323209055804682074564005014776547535959114226010493
d =
72818963105077629740558410461847080457967247911531271148355717844840007560618118158503931879141520737129717539191898962908710378608064897528018640573684648011556192613882739251759874374669201358126911422986850885586463283920904391451268159684723197972233648239891580239064904439566608991520126027809037410483
m =
131
已知n,e,d 可以用以下方法分解n
∵ed=1+h(p−1)(q−1) ∴∀g<n ,有 ged−1=gh(p−1)(q−1)
∵ged−1=1modn ∴pq≡ged−1−1≡0(modn)
令 k=ed−1 ,则: pq≡gk−1≡(gk/2−1)(gk/2+1)≡0(modn)
不难发现,如果 gk/2−1 在 mod n下 如果等于p或者q,那么就可以分解n了.
持续分解(gk−1)=(gk1−1)(gk1+1)(gk2+1)…(gkn+1)(gk/2+1)
如果直到不能再分解那么说明失败 可以换一个 g 继续尝试. 如果成功,那么就说明找到了(gki−1 必须不为0)
#output:p,which is one factor of n defgetpq(n,e,d): whileTrue: k = e * d - 1 g = random.randint(0, n) while k%2==0: k=k//2 temp=gmpy2.powmod(g,k,n)-1 if gmpy2.gcd(temp,n)>1and temp!=0: return gmpy2.gcd(temp,n)
defegcd(a, b): if a == 0: return (b, 0, 1) else: g, y, x = egcd(b % a, a) return (g, x - (b // a) * y, y)
N = 188115669939527035644766943794256836704505079895306601119938518634078379404429524926183546093986493443422022468844644307633083886388295943602507953702360632321739073592477683222131866451975315695813478098524853358977564134499058448438525811837376172990710150323209055804682074564005014776547535959114226010493
p = getpq(N,e2,d2) q = N//p assert p*q == N
phi = (p-1)*(q-1)
s = egcd(phi,e1) assert s[2]*e1%phi == 1
m = pow(c1,s[2],N) print("d:") print(s[2]) print("m:") print(m)
选做题:RSA攻击2
在不分解n的前提下,求d。
给定:
e = 14058695417015334071588010346586749790539913287499707802938898719199384604316115908373997739604466972535533733290829894940306314501336291780396644520926473
n = 33608051123287760315508423639768587307044110783252538766412788814888567164438282747809126528707329215122915093543085008547092423658991866313471837522758159
说明过程。
低私钥指数攻击(e大d小,Wiener Attack)
phi(n)=(p−1)(q−1)=pq−(p+q)+1=N−(p+q)+1
∵p,q 非常大
∴pq>>p+q
∴phi(n)≈N
∵ed≡1modphi(n)
∴ed=1+k∗phi(n)
∴phi(n)e−dk=d∗phi(n)1
∵phi(n)≈N
∴Ne−dk=d∗phi(n)1
同样 d∗phi(n) 很大
∴Ne 略大于 dk
因为 e 和 N 知道,所以计算出 Ne 后,比它略小的 dk 可以通过计算 $\frac{e}{N} $的连分数展开,依次算出这个分数的每一个渐进分数
#sage defrational_to_contfrac(x,y): # Converts a rational x/y fraction into a list of partial quotients [a0, ..., an] a = x // y pquotients = [a] while a * y != x: x, y = y, x - a * y a = x // y pquotients.append(a) return pquotients
defconvergents_from_contfrac(frac): # computes the list of convergents using the list of partial quotients convs = []; for i inrange(len(frac)): convs.append(contfrac_to_rational(frac[0 : i])) return convs
defcontfrac_to_rational (frac): # Converts a finite continued fraction [a0, ..., an] to an x/y rational. iflen(frac) == 0: return (0,1) num = frac[-1] denom = 1 for _ inrange(-2, -len(frac) - 1, -1): num, denom = frac[_] * num + denom, num return (num, denom)
e = 14058695417015334071588010346586749790539913287499707802938898719199384604316115908373997739604466972535533733290829894940306314501336291780396644520926473
n = 33608051123287760315508423639768587307044110783252538766412788814888567164438282747809126528707329215122915093543085008547092423658991866313471837522758159
defegcd(a, b): if a == 0: return (b, 0, 1) g, x, y = egcd(b % a, a) return (g, y - (b // a) * x, x)
defmod_inv(a, m): g, x, _ = egcd(a, m) return (x + m) % m
defisqrt(n): x = n y = (x + 1) // 2 while y < x: x = y y = (x + n // x) // 2 return x defcrack_rsa(e, n): frac = rational_to_contfrac(e, n) convergents = convergents_from_contfrac(frac) for (k, d) in convergents: if k != 0and (e * d - 1) % k == 0: phi = (e * d - 1) // k s = n - phi + 1 # check if x*x - s*x + n = 0 has integer roots D = s * s - 4 * n if D >= 0: sq = isqrt(D) if sq * sq == D and (s + sq) % 2 == 0: return d
p = 2901594209141588502650222215814396586003195843612160434765689337683632253922307845012747360431881459197582849873533200212023894921607275433777719963916949