Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Avatar for 18.783 Fall 2025.
Download
21 views
ubuntu2404
Kernel: SageMath 10.7

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.1589527839999998 Weierstrass time: 0.197690347

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^2 * 5 * 79 * 83 * 96179 * 1144523 1 (1.072s per iteration) 2^5 * 3 * 11 * 503 * 509 * 480543587 2 (1.077s per iteration) 2^4 * 3 * 17 * 107 * 1488019192081 3 (1.070s per iteration) 2^3 * 3^3 * 1481 * 406138031353 4 (1.070s per iteration) 2^2 * 3 * 80107319 * 135154039 5 (1.070s per iteration) 2^2 * 3^2 * 119299 * 30251239069 6 (1.102s per iteration) 2^2 * 3 * 673 * 3079 * 5224881833 7 (1.095s per iteration) 2^4 * 3 * 5 * 677 * 270701 * 2953879 8 (1.086s per iteration) 2^4 * 3 * 11 * 246064265846041 9 (1.078s per iteration) 2^5 * 3^3 * 31 * 140639 * 34490641 10 (1.074s per iteration) 2^3 * 3 * 1845583 * 2933172791 11 (1.071s per iteration) 2^5 * 3 * 5 * 7 * 19 * 107 * 19019794229 12 (1.068s per iteration) 2^4 * 3^2 * 5^3 * 7217885141629 13 (1.070s per iteration) 2^6 * 3^2 * 5 * 29 * 1555578697661 14 (1.068s per iteration) 2^3 * 3^2 * 7 * 14437 * 17855621737 15 (1.070s per iteration) 2^4 * 3 * 11 * 229 * 257 * 4180997827 16 (1.071s per iteration) 2^2 * 3^2 * 131 * 27549179930101 17 (1.069s per iteration) 2^3 * 3 * 7^2 * 71 * 18251 * 85257017 18 (1.068s per iteration) 2^3 * 3 * 11 * 29 * 3307 * 5131523861 19 (1.069s per iteration) 2^2 * 3 * 7 * 47 * 163 * 267511 * 754703 20 (1.072s per iteration) 2^3 * 3 * 11^3 * 581261 * 6997163 21 (1.073s per iteration) 2^4 * 3 * 13 * 6067 * 34318151269 22 (1.077s per iteration) 2^3 * 3^2 * 1804471279963397 23 (1.076s per iteration) 2^3 * 3 * 5 * 53 * 275167 * 74238469 24 (1.085s per iteration) 2^2 * 3 * 139 * 421 * 185013887683 25 (1.089s per iteration) 2^4 * 3 * 227 * 1559 * 9871 * 774833 26 (1.087s per iteration) 2^4 * 3 * 2706706916292083 27 (1.086s per iteration) 2^2 * 3 * 211 * 2061041 * 24896147 28 (1.084s per iteration) 2^2 * 3^3 * 13 * 643 * 143914446259 29 (1.083s per iteration) 2^3 * 3 * 7 * 11 * 70304075867491 30 (1.082s per iteration) 2^2 * 3 * 5 * 7 * 116381 * 2657976257 31 (1.083s per iteration) 2^4 * 3 * 211 * 6829 * 1878458767 32 (1.084s per iteration) 2^3 * 3^2 * 29 * 131 * 223 * 3911 * 544613 33 (1.085s per iteration) 2^2 * 3^2 * 53 * 101 * 139 * 1051 * 2063 * 2237 129921932302713011 ECM time: 36.08956571 129921932302713011