Contact
CoCalc Logo Icon
StoreFeaturesDocsShareSupport News AboutSign UpSign In
| Download

Lecture 10 Toy implementation of ECM

Views: 26
License: AGPL3
Image: ubuntu2204
Kernel: SageMath 9.8

Montgomery curve group operations

def madd(P,Q,R): """Montgomery addition: returns (x_{m+n},z_{m+n}) given P=(x_m,z_m), Q=(x_n,z_n), and R=(x_{m-n},z_{m-n})""" a = P[0]-P[1]; b=P[0]+P[1]; c=Q[0]-Q[1]; d=Q[0]+Q[1] e=a*d; f=b*c; return (R[1]*(e+f)^2,R[0]*(e-f)^2) def mdbl(P,C): """Montgomery doubling: returns (x_{2n},z_{2n}) given P=(x_n,z_n) and C=(A+2)/4 where By^2=x^3+Ax^2+x is the Montgomery curve equation""" a=P[0]+P[1]; b=P[0]-P[1] c=a^2; d=b^2; e=c-d return (c*d,e*(d+C*e)) def mmul(P,n,C): """Montgomery multiplication: returns (x_n,z_n) given P=(x_1,z_1) and C=(A+2)/4 where By^2=x^3+Ax^2+x is the Montgomery curve equation""" Q = [P,mdbl(P,C)] b=n.digits(2) for i in range(len(b)-2,-1,-1): Q[1-b[i]] = madd(Q[1],Q[0],P) Q[b[i]] = mdbl(Q[b[i]],C) return Q[0]
F=GF(random_prime(2^256,2^255)) A=F.random_element(); B=F.random_element() C=(A+2)/4 while true: x = F.random_element() if ((x^3+A*x^2+x)/B).is_square(): break; P=(x,1); t=cputime() for p in primes(0,10000): P=mmul(P,p,C) print("Montgomery time: %s" % (cputime()-t)) a4=1/B^2-A^2/(3*B^2); a6=-A^3/(27*B^3)-a4*A/(3*B) E=EllipticCurve([a4,a6]) P=E.random_element() t=cputime() for p in primes(0,10000): P=p*P print("Weierstrass time: %s" % (cputime()-t))
Montgomery time: 0.15412800000001425 Weierstrass time: 0.17192799999997987

Single stage ECM using Montgomery curves

def L(a,c,N): z = ceil(exp(c*log(N)^a*log(log(N))^(1-a))) return ceil(z) def ECM_1curve(N,p,M,B1): R=Integers(N) # generate Montgomery curve using parameterization that guarantees a point of order 3 c=R(randint(1,10^10)) a=6*c/(c^2+6) b=R(randint(1,10^10)) A=(-3*a^4-6*a^2+1)/(4*a^3) B=(a^2-1)^2/(4*a*b^2) C=(A+2)/4 P=(3*a/4,1) a4=1/B^2-A^2/(3*B^2); a6=-A^3/(27*B^3)-a4*A/(3*B) F=GF(p) E=EllipticCurve([F(a4.lift()),F(a6.lift())]) print(factor(E.cardinality())) m=ceil(M+2*sqrt(M)+1) for p in primes(B1): q = p; r=p*q while r <= m: q=r; r=p*q P=mmul(P,q,C) d=gcd(N,P[1].lift()) if d == N: print("N fail"); return 0 if d > 1: return d return 0
k=57; n=830 q=random_prime(2^(n-k),2^(n-k-1)) p=random_prime(2^k,2^(k-1)) B=2.5*L(1/2,1/sqrt(2),2^k) # includes an empirical fudge factor print("B = %d" % B) print("Expected number of iterations is about %s " % L(1/2,1/(2*sqrt(2)),2^k)) t=cputime() i=1 while true: d = ECM_1curve(p*q,p,2^50,B) if d: break print("%d (%.3fs per iteration)"%(i,(cputime()-t)/i)), i += 1 print(d) print("ECM time: %s" % (cputime()-t)) print(p)
B = 12565 Expected number of iterations is about 71 2^2 * 3 * 13 * 373 * 1897473870277 1 (0.956s per iteration) 2^2 * 3^2 * 167 * 18364971757009 2 (0.965s per iteration) 2^3 * 3 * 14423 * 318964530551 3 (0.967s per iteration) 2^6 * 3^3 * 5 * 13 * 23 * 42738995059 4 (0.983s per iteration) 2^2 * 3^2 * 5 * 17 * 347 * 103982039851 5 (0.970s per iteration) 2^2 * 3 * 67 * 137326131123343 6 (0.972s per iteration) 2^2 * 3^3 * 5 * 7 * 53 * 207287 * 2658701 7 (0.974s per iteration) 2^2 * 3 * 5^2 * 37 * 43 * 709 * 326265809 8 (0.980s per iteration) 2^3 * 3^5 * 5 * 11359075084913 9 (0.977s per iteration) 2^3 * 3 * 7 * 1447 * 176191 * 2577791 10 (0.977s per iteration) 2^2 * 3^2 * 29 * 5641 * 18747900389 11 (0.977s per iteration) 2^9 * 3 * 5 * 3089 * 4654039939 12 (0.976s per iteration) 2^9 * 3^2 * 167 * 143476341361 13 (0.975s per iteration) 2^2 * 3^3 * 5 * 37 * 101^2 * 541715177 14 (0.976s per iteration) 2^3 * 3 * 13 * 827 * 427906744579 15 (0.974s per iteration) 2^3 * 3^2 * 96703 * 15857575597 16 (0.975s per iteration) 2^4 * 3 * 2300212714241147 17 (0.978s per iteration) 2^2 * 3^2 * 72623 * 177283 * 238213 18 (0.981s per iteration) 2^4 * 3 * 67 * 71 * 36931 * 13093139 19 (0.980s per iteration) 2^2 * 3 * 107 * 85989260230381 20 (0.980s per iteration) 2^2 * 3^10 * 5^4 * 747922639 21 (0.982s per iteration) 2^6 * 3^4 * 11 * 311 * 6225742693 22 (0.985s per iteration) 2^4 * 3^6 * 7 * 210127 * 6435493 23 (0.986s per iteration) 2^5 * 3^2 * 41 * 9350458147831 24 (0.987s per iteration) 2^2 * 3^2 * 3066950275173559 25 (0.988s per iteration) 2^2 * 3 * 5 * 467 * 1080941 * 3645349 26 (0.988s per iteration) 2^2 * 3 * 7 * 787 * 1009 * 1655251723 27 (0.989s per iteration) 2^2 * 3^2 * 3066950264875801 28 (0.989s per iteration) 2^2 * 3 * 163 * 1031 * 54749696933 29 (0.989s per iteration) 2^2 * 3^2 * 17 * 294347 * 612912103 30 (0.989s per iteration) 2^2 * 3^2 * 7^2 * 409 * 153033793999 31 (0.989s per iteration) 2^3 * 3 * 4600425414676033 32 (0.987s per iteration) 2^4 * 3^2 * 31 * 1721 * 14371568801 33 (0.987s per iteration) 2^5 * 3 * 11 * 131 * 277 * 2881338287 34 (0.987s per iteration) 2^3 * 3 * 29 * 41 * 67 * 73 * 791076491 35 (0.987s per iteration) 2^6 * 3^2 * 5 * 38336878227181 36 (0.986s per iteration) 2^2 * 3^2 * 3066950276807453 37 (0.985s per iteration) 2^2 * 3^2 * 5 * 13 * 17 * 293 * 397 * 23860873 38 (0.985s per iteration) 2^4 * 3^4 * 8069 * 10558069583 39 (0.985s per iteration) 2^2 * 3^2 * 2347 * 1306753424213 40 (0.985s per iteration) 2^4 * 3 * 5 * 109 * 4220573786153 41 (0.985s per iteration) 2^7 * 3^2 * 19 * 419 * 52889 * 227627 42 (0.986s per iteration) 2^5 * 3 * 13 * 103 * 858929312779 43 (0.986s per iteration) 2^2 * 3^2 * 7 * 28151 * 15563772313 44 (0.985s per iteration) 2^4 * 3^2 * 11^2 * 6336674101679 45 (0.986s per iteration) 2^5 * 3^2 * 43 * 1439 * 6195658883 46 (0.985s per iteration) 2^2 * 3^3 * 7 * 3947 * 37001583947 47 (0.985s per iteration) 2^3 * 3 * 2287 * 75431 * 26667479 48 (0.985s per iteration) 2^3 * 3^4 * 170386126077137 49 (0.985s per iteration) 2^2 * 3 * 5 * 31027489 * 59307737 50 (0.985s per iteration) 2^3 * 3 * 179 * 17099 * 1503052849 51 (0.985s per iteration) 2^3 * 3^2 * 17 * 37 * 7411 * 328964687 52 (0.985s per iteration) 2^4 * 3 * 2300212697705411 53 (0.986s per iteration) 2^2 * 3 * 5 * 7 * 11 * 607 * 6899 * 5706797 54 (0.985s per iteration) 2^4 * 3^2 * 6763 * 113372404421 55 (0.986s per iteration) 2^2 * 3 * 5 * 233 * 7897726017347 56 (0.986s per iteration) 2^2 * 3 * 31 * 608941 * 487406233 57 (0.986s per iteration) 2^3 * 3^2 * 11 * 29 * 281 * 1039 * 16465093 58 (0.987s per iteration) 2^2 * 3 * 5 * 13 * 199 * 1229 * 578774881 59 (0.987s per iteration) 2^2 * 3^3 * 7 * 19 * 23 * 150067 * 2227003 60 (0.987s per iteration) 2^3 * 3^2 * 7 * 4965833 * 44115031 61 (0.986s per iteration) 2^2 * 3 * 2293 * 4012582125829 62 (0.987s per iteration) 2^7 * 3^7 * 5^2 * 17 * 928029007 63 (0.987s per iteration) 2^5 * 3^2 * 7 * 563 * 661 * 147166463 64 (0.987s per iteration) 2^2 * 3^2 * 5 * 79 * 7764431025269 65 (0.987s per iteration) 2^2 * 3^2 * 5 * 631 * 4679 * 207756359 66 (0.986s per iteration) 2^4 * 3^4 * 5^2 * 11 * 103 * 293 * 10265183 67 (0.986s per iteration) 2^2 * 3^2 * 5 * 11 * 24967 * 2233457441 68 (0.987s per iteration) 2^2 * 3^2 * 7 * 31 * 743 * 19022088011 69 (0.987s per iteration) 2^2 * 3^3 * 11 * 181 * 863 * 594981449 70 (0.986s per iteration) 2^2 * 3 * 139 * 1691113 * 39141779 71 (0.987s per iteration) 2^2 * 3 * 43 * 79 * 313 * 4787 * 1807693 72 (0.987s per iteration) 2^2 * 3^2 * 5 * 19 * 32283687001669 73 (0.987s per iteration) 2^3 * 3 * 4600425431722663 74 (0.987s per iteration) 2^3 * 3 * 4600425429711053 75 (0.987s per iteration) 2^3 * 3^2 * 11 * 7687 * 18135401429 76 (0.986s per iteration) 2^12 * 3^2 * 7 * 113 * 3786433153 77 (0.986s per iteration) 2^4 * 3 * 5 * 460042539045569 78 (0.987s per iteration) 2^3 * 3 * 5 * 11^2 * 157 * 2767 * 17503859 79 (0.987s per iteration) 2^6 * 3 * 7 * 51973 * 1580637127 80 (0.986s per iteration) 2^2 * 3 * 69023419 * 133300421 81 (0.987s per iteration) 2^2 * 3 * 5^2 * 1033 * 110129 * 3235087 82 (0.987s per iteration) 2^3 * 3 * 5 * 38707 * 40087 * 592973 83 (0.987s per iteration) 2^2 * 3 * 9200850834129637 84 (0.986s per iteration) 2^2 * 3^3 * 7^2 * 67 * 5591 * 55696141 85 (0.986s per iteration) 2^4 * 3 * 49633 * 46344421969 86 (0.986s per iteration) 2^2 * 3^2 * 11 * 137 * 211 * 9645195317 87 (0.987s per iteration) 2^3 * 3^2 * 5 * 139 * 1063 * 2075671733 88 (0.987s per iteration) 2^2 * 3 * 5 * 13 * 347 * 407929541737 89 (0.986s per iteration) 2^2 * 3^2 * 11 * 22567 * 32789 * 376801 90 (0.987s per iteration) 2^3 * 3^2 * 5 * 7^2 * 37 * 126491 * 1337363 91 (0.987s per iteration) 2^2 * 3^2 * 5 * 19 * 321911 * 100287617 92 (0.987s per iteration) 2^2 * 3 * 23 * 139 * 30509 * 94331639 93 (0.987s per iteration) 2^4 * 3^2 * 61 * 12569468305787 94 (0.987s per iteration) 2^7 * 3^2 * 29 * 3304903294967 95 (0.988s per iteration) 2^2 * 3^3 * 29 * 78301 * 450215221 96 (0.988s per iteration) 2^2 * 3^4 * 31 * 2243 * 4900870867 97 (0.988s per iteration) 2^3 * 3 * 13^2 * 17 * 1601261887213 98 (0.989s per iteration) 2^2 * 3 * 41041877 * 224182019 99 (0.990s per iteration) 2^3 * 3^3 * 233 * 2193812781739 100 (0.991s per iteration) 2^2 * 3^2 * 11 * 1307 * 213323382703 101 (0.992s per iteration) 2^4 * 3^2 * 766737566485489 102 (0.992s per iteration) 2^2 * 3 * 8963 * 1026536962153 103 (0.992s per iteration) 2^4 * 3 * 5 * 10140017 * 45369011 104 (0.991s per iteration) 2^2 * 3^4 * 340772251977217 105 (0.991s per iteration) 2^2 * 3 * 5^2 * 17 * 31 * 419 * 1901 * 876761 106 (0.991s per iteration) 2^2 * 3 * 9613 * 957125849951 107 (0.991s per iteration) 2^8 * 3 * 37 * 387857 * 10017853 108 (0.991s per iteration) 2^3 * 3 * 11 * 41^2 * 283 * 3691 * 238181 109 (0.991s per iteration) 2^2 * 3^3 * 1022316752836571 110 (0.990s per iteration) 2^3 * 3 * 7^2 * 23 * 89 * 7333 * 6254641 111 (0.990s per iteration) 2^7 * 3 * 5^2 * 107 * 107486575219 112 (0.990s per iteration) 2^4 * 3^2 * 149 * 1936679 * 2657069 113 (0.990s per iteration) 2^2 * 3 * 7 * 17 * 79 * 151 * 6481521821 114 (0.990s per iteration) 2^4 * 3^2 * 499 * 1536548226937 115 (0.990s per iteration) 2^4 * 3^4 * 647 * 131673976601 116 (0.989s per iteration) 2^6 * 3^3 * 29 * 126013 * 17484457 117 (0.989s per iteration) 2^2 * 3 * 5 * 13 * 137 * 15319 * 67447157 118 (0.989s per iteration) 2^2 * 3 * 5 * 7 * 7000129 * 37553801 119 (0.989s per iteration) 2^2 * 3 * 1637 * 5620556379631 120 (0.989s per iteration) 2^2 * 3 * 19 * 937 * 516814625479 121 (0.989s per iteration) 2^4 * 3 * 23 * 32717 * 3056797637 122 (0.989s per iteration) 2^6 * 3 * 17 * 73 * 2297 * 201732203 123 (0.989s per iteration) 2^4 * 3 * 61 * 107 * 549247 * 641633 124 (0.989s per iteration) 2^2 * 3^2 * 37 * 107 * 148667 * 5210827 125 (0.989s per iteration) 2^3 * 3^2 * 7 * 3719 * 58905049057 126 (0.989s per iteration) 2^2 * 3^2 * 1181 * 2596909633457 127 (0.989s per iteration) 2^2 * 3^2 * 17 * 456241 * 395424433 128 (0.989s per iteration) 2^5 * 3^2 * 5 * 41 * 1907 * 980645851 129 (0.989s per iteration) 2^2 * 3^3 * 5 * 23 * 4177 * 2128252561 130 (0.989s per iteration) 2^2 * 3^3 * 5^2 * 29 * 31 * 37 * 577 * 2130631 131 (0.989s per iteration) 2^2 * 3 * 125197 * 73490984587 132 (0.989s per iteration) 2^2 * 3^2 * 17 * 1297 * 352049 * 395107 133 (0.989s per iteration) 2^2 * 3^2 * 5^2 * 31 * 37 * 1327 * 80599507 134 (0.989s per iteration) 2^2 * 3 * 5 * 7 * 23 * 11429628302527 135 (0.989s per iteration) 2^3 * 3 * 7 * 17 * 271 * 2003 * 71219807 136 (0.989s per iteration) 2^2 * 3^3 * 5^4 * 13 * 125823600703 137 (0.989s per iteration) 2^7 * 3 * 4468273 * 64348483 138 (0.989s per iteration) 2^7 * 3^2 * 73 * 1312906797637 139 (0.989s per iteration) 2^2 * 3 * 433 * 9341 * 2274818333 140 (0.989s per iteration) 2^3 * 3^3 * 47 * 33349 * 326118031 141 (0.989s per iteration) 2^2 * 3 * 362429 * 25386629623 142 (0.989s per iteration) 2^2 * 3^2 * 5 * 89 * 109097 * 63173351 143 (0.989s per iteration) 2^3 * 3 * 5 * 17 * 907 * 59672162867 144 (0.989s per iteration) 2^2 * 3^2 * 53 * 553057 * 104631143 145 (0.988s per iteration) 2^3 * 3^3 * 5 * 971 * 105284938727 146 (0.988s per iteration) 2^2 * 3 * 7 * 71 * 18512778364603 147 (0.988s per iteration) 2^3 * 3^2 * 389 * 3942095479327 148 (0.988s per iteration) 2^2 * 3^2 * 17 * 389 * 463775935523 149 (0.988s per iteration) 2^3 * 3^2 * 5^2 * 5743 * 10680655619 150 (0.988s per iteration) 2^2 * 3 * 37 * 248671643531327 151 (0.988s per iteration) 2^2 * 3 * 13 * 707757754952153 152 (0.988s per iteration) 2^7 * 3^2 * 95842195844123 153 (0.988s per iteration) 2^5 * 3^3 * 79 * 1617589811723 154 (0.988s per iteration) 2^5 * 3^2 * 5 * 76673756714833 155 (0.988s per iteration) 2^2 * 3^2 * 3066950284514609 156 (0.988s per iteration) 2^2 * 3 * 11 * 836440984361063 157 (0.988s per iteration) 2^4 * 3 * 7 * 328601816241233 158 (0.988s per iteration) 2^3 * 3^2 * 131 * 271 * 43195265891 159 (0.988s per iteration) 2^3 * 3 * 71 * 64794724103059 160 (0.988s per iteration) 2^3 * 3^2 * 1148339 * 1335385399 161 (0.988s per iteration) 2^3 * 3^2 * 109 * 137 * 1399 * 2161 * 33967 162 (0.988s per iteration) 2^4 * 3^2 * 766737571098601 163 (0.988s per iteration) 2^3 * 3^3 * 23 * 22224277280963 164 (0.988s per iteration) 2^2 * 3^2 * 5 * 71 * 239 * 431 * 83869337 165 (0.988s per iteration) 2^5 * 3 * 59 * 919 * 119611 * 177337 166 (0.989s per iteration) 2^2 * 3^2 * 43 * 71324425227863 167 (0.989s per iteration) 2^2 * 3^2 * 101 * 30365844196343 168 (0.989s per iteration) 2^2 * 3^3 * 5^2 * 13 * 7237 * 14303 * 30389 169 (0.989s per iteration) 2^2 * 3^3 * 7 * 13 * 792307 * 14179163 170 (0.989s per iteration) 2^5 * 3 * 173 * 6648013623617 171 (0.989s per iteration) 2^3 * 3^3 * 211 * 2422551554399 172 (0.989s per iteration) 2^2 * 3 * 7 * 241 * 1747 * 3121907281 173 (0.990s per iteration) 2^2 * 3^2 * 5 * 613390053115769 174 (0.989s per iteration) 2^2 * 3 * 59 * 155946623368031 175 (0.990s per iteration) 2^2 * 3^2 * 13 * 947 * 249122758999 176 (0.989s per iteration) 2^2 * 3^2 * 5 * 23 * 1609717 * 16567591 177 (0.990s per iteration) 2^3 * 3^4 * 1231 * 2521 * 6869 * 7993 110410209833111497 ECM time: 175.806915 110410209833111497