This repository has been archived by the owner on Mar 8, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
ac31ee4
commit 9aa42b1
Showing
49 changed files
with
2,092 additions
and
0 deletions.
There are no files selected for viewing
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
load("coppersmith_method.sage") | ||
p = 1379321 | ||
q = 1571023 | ||
n = p*q | ||
e = 5 | ||
d = 197314381133 | ||
M = 612301 | ||
for i in range(-10,10): | ||
MA = M + i | ||
C = 384635054622 | ||
R.< x > = ZZ [ ] | ||
f = ( MA + x ) ^ e - C | ||
print i | ||
print coppersmith(f , p *q , 0.01 , True) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
|
||
# This file was *autogenerated* from the file 2test.sage | ||
from sage.all_cmdline import * # import sage library | ||
|
||
_sage_const_384635054622 = Integer(384635054622); _sage_const_0p01 = RealNumber('0.01'); _sage_const_5 = Integer(5); _sage_const_1571023 = Integer(1571023); _sage_const_197314381133 = Integer(197314381133); _sage_const_10 = Integer(10); _sage_const_1379321 = Integer(1379321); _sage_const_612301 = Integer(612301) | ||
load("coppersmith_method.sage") | ||
p = _sage_const_1379321 | ||
q = _sage_const_1571023 | ||
n = p*q | ||
e = _sage_const_5 | ||
d = _sage_const_197314381133 | ||
M = _sage_const_612301 | ||
for i in range(-_sage_const_10 ,_sage_const_10 ): | ||
MA = M + i | ||
C = _sage_const_384635054622 | ||
R = ZZ ['x']; (x,) = R._first_ngens(1) | ||
f = ( MA + x ) ** e - C | ||
print i | ||
print coppersmith(f , p *q , _sage_const_0p01 , True) | ||
|
||
|
48 changes: 48 additions & 0 deletions
48
daedalus/daedalus2/attacks/coppersmith/coppersmith_method.sage
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
def coppersmith (f , N , epsilon=0.001 , fastLLL=False, debug=False ) : | ||
if epsilon > 1 / 7.0 or epsilon <= 0 : | ||
print ( " invalid epsilon " ) | ||
return None | ||
f.change_ring ( Integers ( N ) ) | ||
delta=f.degree ( ) | ||
m=ceil ( 1 /(delta* epsilon) ) | ||
R.< x >=ZZ [ ] | ||
# construction of the g [i , j ]( x ) | ||
g=[] | ||
for j in range (0 , delta ) : | ||
g.append ( [ ] ) | ||
for i in range (1 , m + 1 ) : | ||
g [ j ].append ( x ^ j * N ^ ( i ) * f ^ ( m - i ) ) | ||
X=ceil ( 0.5 * N ^ ( 1 / delta - epsilon ) ) | ||
if debug : print ( " X=" + str ( X ) ) | ||
size=m * delta | ||
# construct B from g [i , j ]( X * x ) | ||
B=matrix ( ZZ , size , size ) | ||
compteur=0 | ||
|
||
for i in range ( - m +1 , 1 ) : | ||
for j in range (0 , delta ) : | ||
polylist=g [ j ] [ - i ] ( X * x ).list ( ) | ||
vector=[ 0 ] * size | ||
vector [ 0 : len ( polylist ) ]=polylist | ||
vector.reverse ( ) | ||
B.set_column ( compteur , vector ) | ||
compteur=compteur + 1 | ||
if debug : show ( B ) | ||
if debug : print " LLL starts " | ||
coeffs=[ ] | ||
coeffs = B.transpose ( ).LLL( ).transpose ( ).column ( 0 ).list ( ) | ||
coeffs.reverse ( ) | ||
g=0*x | ||
for i in range (0 , size ) : | ||
g=g + Integer ( coeffs [ i ] / X ^ i ) * x ^ i | ||
roots=g.roots ( multiplicities=False ) | ||
result=[ ] | ||
|
||
for i in range (0 , len ( roots ) ) : | ||
if gcd (N , f ( roots [ i ] ) ) >=N : | ||
result.append ( roots [ i ] ) | ||
return result | ||
|
||
R.< x >=ZZ [ ] | ||
f=( x - 1 ) * ( x - 2 ) * ( x - 3 ) * ( x - 4 ) * ( x - 40 ) | ||
print coppersmith (f , 10000 ) |
54 changes: 54 additions & 0 deletions
54
daedalus/daedalus2/attacks/coppersmith/coppersmith_method.sage.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
|
||
# This file was *autogenerated* from the file coppersmith_method.sage | ||
from sage.all_cmdline import * # import sage library | ||
|
||
_sage_const_3 = Integer(3); _sage_const_2 = Integer(2); _sage_const_1 = Integer(1); _sage_const_0 = Integer(0); _sage_const_4 = Integer(4); _sage_const_10000 = Integer(10000); _sage_const_40 = Integer(40); _sage_const_0p1 = RealNumber('0.1'); _sage_const_0p5 = RealNumber('0.5'); _sage_const_7p0 = RealNumber('7.0') | ||
def coppersmith (f , N , epsilon=_sage_const_0p1 , fastLLL=False, debug=False ) : | ||
if epsilon > _sage_const_1 / _sage_const_7p0 or epsilon <= _sage_const_0 : | ||
print ( " invalid epsilon " ) | ||
return None | ||
f.change_ring ( Integers ( N ) ) | ||
delta=f.degree ( ) | ||
m=ceil ( _sage_const_1 / delta / epsilon ) | ||
R = ZZ ['x']; (x,) = R._first_ngens(1) | ||
# construction of the g [i , j ]( x ) | ||
g=[] | ||
for j in range (_sage_const_0 , delta ) : | ||
g.append ( [ ] ) | ||
for i in range (_sage_const_1 , m + _sage_const_1 ) : | ||
g [ j ].append ( x ** j * N ** ( i ) * f ** ( m - i ) ) | ||
X=ceil ( _sage_const_0p5 * N ** ( _sage_const_1 / delta - epsilon ) ) | ||
if debug : print ( " X=" + str ( X ) ) | ||
size=m * delta | ||
# construct B from g [i , j ]( X * x ) | ||
B=matrix ( ZZ , size , size ) | ||
compteur=_sage_const_0 | ||
|
||
for i in range ( - m +_sage_const_1 , _sage_const_1 ) : | ||
for j in range (_sage_const_0 , delta ) : | ||
polylist=g [ j ] [ - i ] ( X * x ).list ( ) | ||
vector=[ _sage_const_0 ] * size | ||
vector [ _sage_const_0 : len ( polylist ) ]=polylist | ||
vector.reverse ( ) | ||
B.set_column ( compteur , vector ) | ||
compteur=compteur + _sage_const_1 | ||
if debug : show ( B ) | ||
if debug : print " LLL starts " | ||
coeffs=[ ] | ||
coeffs = B.transpose ( ).LLL( ).transpose ( ).column ( _sage_const_0 ).list ( ) | ||
coeffs.reverse ( ) | ||
g=_sage_const_0 *x | ||
for i in range (_sage_const_0 , size ) : | ||
g=g + Integer ( coeffs [ i ] / X ** i ) * x ** i | ||
roots=g.roots ( multiplicities=False ) | ||
result=[ ] | ||
|
||
for i in range (_sage_const_0 , len ( roots ) ) : | ||
if gcd (N , f ( roots [ i ] ) ) >=N : | ||
result.append ( roots [ i ] ) | ||
return result | ||
|
||
R = ZZ ['x']; (x,) = R._first_ngens(1) | ||
f=( x - _sage_const_1 ) * ( x - _sage_const_2 ) * ( x - _sage_const_3 ) * ( x - _sage_const_4 ) * ( x - _sage_const_40 ) | ||
print coppersmith (f , _sage_const_10000 ) | ||
|
154 changes: 154 additions & 0 deletions
154
daedalus/daedalus2/attacks/coppersmith/partial_message_exposure/coppersmith.sage
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
import time | ||
|
||
debug = True | ||
|
||
#display the matrix(lower triangular) | ||
def matrix_overview(BB,bound): | ||
for ii in range(BB.dimensions()[0]): | ||
a = ('%02d' %ii) | ||
for jj in range(BB.dimensions()[1]): | ||
a += '0' if BB[ii,jj] == 0 else 'X' | ||
a += ' ' | ||
if BB[ii,ii] >=bound: | ||
a += '~' | ||
print a | ||
|
||
def coppersmith_howgrave_graham(pol, modulus, beta, mm, tt, XX): | ||
|
||
dd = pol.degree() | ||
nn = dd*mm + tt | ||
# | ||
# checks | ||
# | ||
if not 0 < beta <= 1: | ||
raise ValueError("beta should belongs in (0, 1]") | ||
|
||
if not pol.is_monic(): | ||
raise ArithmeticError("Polynomial must be monic.") | ||
|
||
# | ||
# calculate bounds and display them | ||
# | ||
""" | ||
* we want to find g(x) such that ||g(xX)|| <= b^m / sqrt(n) | ||
* we know LLL will give us a short vector v such that: | ||
||v|| <= 2^((n - 1)/4) * det(L)^(1/n) | ||
* we will use that vector as a coefficient vector for our g(x) | ||
* so we want to satisfy: | ||
2^((n - 1)/4) * det(L)^(1/n) < N^(beta*m) / sqrt(n) | ||
so we can obtain ||v|| < N^(beta*m) / sqrt(n) <= b^m / sqrt(n) | ||
(it's important to use N because we might not know b) | ||
""" | ||
if debug: | ||
# t optimized? | ||
print "\n# Optimized t?\n" | ||
print "we want X^(n-1) < N^(beta*m) so that each vector is helpful" | ||
cond1 = RR(XX^(nn-1)) | ||
print "* X^(n-1) = ", cond1 | ||
cond2 = pow(modulus, beta*mm) | ||
print "* N^(beta*m) = ", cond2 | ||
print "* X^(n-1) < N^(beta*m) \n-> GOOD" if cond1 < cond2 else "* X^(n-1) >= N^(beta*m) \n-> NOT GOOD" | ||
|
||
# bound for X | ||
print "\n# X bound respected?\n" | ||
print "we want X <= N^(((2*beta*m)/(n-1)) - ((delta*m*(m+1))/(n*(n-1)))) / 2 = M" | ||
print "* X =", XX | ||
cond2 = RR(modulus^(((2*beta*mm)/(nn-1)) - ((dd*mm*(mm+1))/(nn*(nn-1)))) / 2) | ||
print "* M =", cond2 | ||
print "* X <= M \n-> GOOD" if XX <= cond2 else "* X > M \n-> NOT GOOD" | ||
|
||
# solution possible? | ||
print "\n# Solutions possible?\n" | ||
detL = RR(modulus^(dd * mm * (mm + 1) / 2) * XX^(nn * (nn - 1) / 2)) | ||
print "we can find a solution if 2^((n - 1)/4) * det(L)^(1/n) < N^(beta*m) / sqrt(n)" | ||
cond1 = RR(2^((nn - 1)/4) * detL^(1/nn)) | ||
print "* 2^((n - 1)/4) * det(L)^(1/n) = ", cond1 | ||
cond2 = RR(modulus^(beta*mm) / sqrt(nn)) | ||
print "* N^(beta*m) / sqrt(n) = ", cond2 | ||
print "* 2^((n - 1)/4) * det(L)^(1/n) < N^(beta*m) / sqrt(n) \n-> SOLUTION WILL BE FOUND" if cond1 < cond2 else "* 2^((n - 1)/4) * det(L)^(1/n) >= N^(beta*m) / sqroot(n) \n-> NO SOLUTIONS MIGHT BE FOUND (but we never know)" | ||
|
||
# warning about X | ||
print "\n# Note that no solutions will be found _for sure_ if you don't respect:\n* |root| < X \n* b >= modulus^beta\n" | ||
|
||
|
||
|
||
#change ring of pol and x | ||
polZ = pol.change_ring(ZZ) | ||
x = polZ.parent().gen() | ||
|
||
gg = [] | ||
for ii in range(mm): | ||
for jj in range(dd): | ||
gg.append((x*XX)**jj *modulus**(mm-ii)*polZ(x*XX)**ii) | ||
for ii in range(tt): | ||
gg.append((x*XX)*ii*polZ(x*XX)*mm) | ||
|
||
BB = Matrix(ZZ,nn) | ||
|
||
for ii in range(nn): | ||
for jj in range(ii+1): | ||
BB[ii,jj] = gg[ii][jj] | ||
|
||
#display basis matrix | ||
if debug: | ||
matrix_overview(BB,modulus^mm) | ||
|
||
#LLL | ||
BB = BB.LLL() | ||
|
||
new_pol = 0 | ||
for ii in range(nn): | ||
new_pol += x*ii*BB[0,ii]/XX**ii | ||
|
||
#factor the polynomial | ||
|
||
potential_roots = new_pol.roots() | ||
print "potential roots: ", potential_roots | ||
|
||
#test roots | ||
roots = [] | ||
for root in potential_roots: | ||
if root[0].is_integer(): | ||
result = polZ(ZZ(root[0])) | ||
if gcd(modulus,result) >= modulus^beta: | ||
roots.append(ZZ(root[0])) | ||
return roots | ||
|
||
#test | ||
|
||
length_N = 1024 | ||
Kbits = 200 #size of root | ||
e = 3 | ||
|
||
p = next_prime(2^int(round(length_N/2))) | ||
q = next_prime(p) | ||
N = p*q | ||
ZmodN = Zmod(N); | ||
|
||
K = ZZ.random_element(0, 2^Kbits) | ||
Kdigits = K.digits(2) | ||
M = [0]*Kbits + [1]*(length_N-Kbits); | ||
for i in range(len(Kdigits)): | ||
M[i] = Kdigits[i] | ||
M = ZZ(M, 2) | ||
C = ZmodN(M)^e | ||
|
||
P.<x> = PolynomialRing(ZmodN) | ||
pol = (2^length_N - 2^Kbits + x)^e - C | ||
dd = pol.degree() | ||
beta = 1 | ||
epsilon = beta/7 | ||
mm = ceil(beta**2/(dd*epsilon)) | ||
tt = 0 | ||
XX = ceil(N**(1/dd)-epsilon) | ||
start_time = time.time() | ||
roots = coppersmith_howgrave_graham(pol, N, beta, mm, tt, XX) | ||
|
||
print "Solutions" | ||
print "we want to find:",str(K) | ||
print "we found:", str(roots) | ||
print(time.time() - start_time) |
Oops, something went wrong.