From 5ac64f139d6d560103d191904f1d563c7491c993 Mon Sep 17 00:00:00 2001 From: Youssef El Housni Date: Mon, 20 Apr 2026 15:40:23 -0400 Subject: [PATCH 1/8] perf: add subgroup membership test for all twistededwards curve --- addchain/1aaaaaab | Bin 0 -> 221 bytes addchain/1c71c71c55555555 | Bin 0 -> 427 bytes ...d939f24f531918901d9cc89c6c833a18bfa0180000 | Bin 0 -> 2294 bytes ...45f741290002e16ba88600000010a1180000000000 | Bin 0 -> 3461 bytes addchain/38e38e38aaaaaaab | Bin 0 -> 435 bytes addchain/3c000000 | Bin 0 -> 206 bytes addchain/3f | Bin 0 -> 90 bytes addchain/3f800000 | Bin 0 -> 212 bytes ...47970dec00566a9dbfb40000004284600000000000 | Bin 0 -> 2232 bytes addchain/54aaaaab | Bin 0 -> 234 bytes ...b6d0302b0ba5067d090f372e12287c3eb27e000000 | Bin 0 -> 2274 bytes addchain/7 | Bin 0 -> 68 bytes addchain/7fffffff | Bin 0 -> 232 bytes addchain/7fffffff80000000 | Bin 0 -> 393 bytes ...fe51b079a9239a3cf232d7e1cf5e00000000000000 | Bin 0 -> 2254 bytes ...03544f435c0843dcbb4a57bca04dfd005fe8060000 | Bin 0 -> 2924 bytes addchain/d555555 | Bin 0 -> 214 bytes ...0101343b00aa77b4805fffcb7fdfffffffe0000000 | Bin 0 -> 2284 bytes ecc/bls12-377/twistededwards/curve.go | 13 + ecc/bls12-377/twistededwards/point_test.go | 75 +++ ecc/bls12-377/twistededwards/subgroup.go | 330 +++++++++++ ecc/bls12-381/bandersnatch/point_test.go | 31 +- ecc/bls12-381/bandersnatch/subgroup.go | 6 + ecc/bls12-381/twistededwards/curve.go | 17 + ecc/bls12-381/twistededwards/point_test.go | 75 +++ ecc/bls12-381/twistededwards/subgroup.go | 426 ++++++++++++++ ecc/bls24-315/twistededwards/curve.go | 17 + ecc/bls24-315/twistededwards/point_test.go | 75 +++ ecc/bls24-315/twistededwards/subgroup.go | 465 +++++++++++++++ ecc/bls24-317/twistededwards/curve.go | 17 + ecc/bls24-317/twistededwards/point_test.go | 75 +++ ecc/bls24-317/twistededwards/subgroup.go | 427 ++++++++++++++ ecc/bn254/twistededwards/curve.go | 17 + ecc/bn254/twistededwards/point_test.go | 75 +++ ecc/bn254/twistededwards/subgroup.go | 476 ++++++++++++++++ ecc/bw6-633/twistededwards/curve.go | 17 + ecc/bw6-633/twistededwards/point_test.go | 75 +++ ecc/bw6-633/twistededwards/subgroup.go | 524 +++++++++++++++++ ecc/bw6-761/twistededwards/curve.go | 17 + ecc/bw6-761/twistededwards/point_test.go | 75 +++ ecc/bw6-761/twistededwards/subgroup.go | 539 ++++++++++++++++++ ...d939f24f531918901d9cc89c6c833a18bfa0180000 | Bin 0 -> 2294 bytes ...45f741290002e16ba88600000010a1180000000000 | Bin 0 -> 3461 bytes ...47970dec00566a9dbfb40000004284600000000000 | Bin 0 -> 2232 bytes ...b6d0302b0ba5067d090f372e12287c3eb27e000000 | Bin 0 -> 2274 bytes ...fe51b079a9239a3cf232d7e1cf5e00000000000000 | Bin 0 -> 2254 bytes ...03544f435c0843dcbb4a57bca04dfd005fe8060000 | Bin 0 -> 2924 bytes ...0101343b00aa77b4805fffcb7fdfffffffe0000000 | Bin 0 -> 2284 bytes internal/generator/config/curve.go | 66 +++ internal/generator/edwards/generate.go | 10 +- .../generator/edwards/template/curve.go.tmpl | 31 +- .../generator/edwards/template/point.go.tmpl | 4 +- .../edwards/template/subgroup.go.tmpl | 269 +++++++++ .../edwards/template/tests/point.go.tmpl | 51 +- 54 files changed, 4266 insertions(+), 29 deletions(-) create mode 100644 addchain/1aaaaaab create mode 100644 addchain/1c71c71c55555555 create mode 100644 addchain/32dbd584953b42564bf8fd939f24f531918901d9cc89c6c833a18bfa0180000 create mode 100644 addchain/35c748c2f8a21d58c760b80d94292763445b3e601ea271e3de6c45f741290002e16ba88600000010a1180000000000 create mode 100644 addchain/38e38e38aaaaaaab create mode 100644 addchain/3c000000 create mode 100644 addchain/3f create mode 100644 addchain/3f800000 create mode 100644 addchain/4aad957a68b2955982d1347970dec00566a9dbfb40000004284600000000000 create mode 100644 addchain/54aaaaab create mode 100644 addchain/60c89ce5c263405370a08b6d0302b0ba5067d090f372e12287c3eb27e000000 create mode 100644 addchain/7 create mode 100644 addchain/7fffffff create mode 100644 addchain/7fffffff80000000 create mode 100644 addchain/887f22fd4d1b5f85a1612fe51b079a9239a3cf232d7e1cf5e00000000000000 create mode 100644 addchain/98474056b0daca1a7ee9317d2f8bd5fbd83a03544f435c0843dcbb4a57bca04dfd005fe8060000 create mode 100644 addchain/d555555 create mode 100644 addchain/e7db4ea6533afa906673b0101343b00aa77b4805fffcb7fdfffffffe0000000 create mode 100644 ecc/bls12-377/twistededwards/subgroup.go create mode 100644 ecc/bls12-381/bandersnatch/subgroup.go create mode 100644 ecc/bls12-381/twistededwards/subgroup.go create mode 100644 ecc/bls24-315/twistededwards/subgroup.go create mode 100644 ecc/bls24-317/twistededwards/subgroup.go create mode 100644 ecc/bn254/twistededwards/subgroup.go create mode 100644 ecc/bw6-633/twistededwards/subgroup.go create mode 100644 ecc/bw6-761/twistededwards/subgroup.go create mode 100644 internal/generator/addchain/32dbd584953b42564bf8fd939f24f531918901d9cc89c6c833a18bfa0180000 create mode 100644 internal/generator/addchain/35c748c2f8a21d58c760b80d94292763445b3e601ea271e3de6c45f741290002e16ba88600000010a1180000000000 create mode 100644 internal/generator/addchain/4aad957a68b2955982d1347970dec00566a9dbfb40000004284600000000000 create mode 100644 internal/generator/addchain/60c89ce5c263405370a08b6d0302b0ba5067d090f372e12287c3eb27e000000 create mode 100644 internal/generator/addchain/887f22fd4d1b5f85a1612fe51b079a9239a3cf232d7e1cf5e00000000000000 create mode 100644 internal/generator/addchain/98474056b0daca1a7ee9317d2f8bd5fbd83a03544f435c0843dcbb4a57bca04dfd005fe8060000 create mode 100644 internal/generator/addchain/e7db4ea6533afa906673b0101343b00aa77b4805fffcb7fdfffffffe0000000 create mode 100644 internal/generator/edwards/template/subgroup.go.tmpl diff --git a/addchain/1aaaaaab b/addchain/1aaaaaab new file mode 100644 index 0000000000000000000000000000000000000000..ab298d417ede2e290f2d03ed6e0258ac58c87daa GIT binary patch literal 221 zcmWlR%L)Nu07lOl6Otrp5|SoKk|arzWXFbAu(A?)0hg!omSg_S*LP2{Po$;u^L~9^ zZf0N1-q3j!G&((kFfSa8(PNH~{qj~y6k#0f*dmrK2UfwVRjgUVx^-;Wz@|-1Ot57O z+qOg6#h$$|>tkvf9PJh0bv9`2l*d)$q1U!|j$9q?Su?E}+r$*!PgSo-0~v{kL|k;nL6yq0{z zkKfY1@Npml1VoUa2obU$VG$u>=}<(8iWo6l9b4~2#EDxvwe!wwm9T4)B1KA^b1u@P zMTU&Xk`*~}B2Qjia3Km5M3JH>Q4(d!qC!PfF&EdUi8^)Bpdp$xMUrdLq9xk2MTd^) z(iJ^=qEBB87>FT5F=8ZcxfNr^V!}jBnTi=RF=s9u9FgErJo79TEX0zfSg{go);8h4 dT;0uo-do(QG2ac0d>9z{G%)gIU;}c$^$T&DL`(nx literal 0 HcmV?d00001 diff --git a/addchain/32dbd584953b42564bf8fd939f24f531918901d9cc89c6c833a18bfa0180000 b/addchain/32dbd584953b42564bf8fd939f24f531918901d9cc89c6c833a18bfa0180000 new file mode 100644 index 0000000000000000000000000000000000000000..d21a756edd01eaf8a10a21cb3959092be9d39632 GIT binary patch literal 2294 zcmXAqab#9|9LB%TxwAVnGcz-5W@ct)W@ct)W@fTGvpX|0GqaoQ&g|~aD>F0Qnn{u* zNs=Tj_31xKHt6PkMsWC^E<1|_9xQsqq%?o&i(a| zvW-x-FJi}kze&lT%M9`bf2bg&A+Hf>(Uvbu)f`C@NkJrqkragrRLrF%p+c3ilrffL z6JJTQAk?Itp+OCXZ+<8=tl`jzMna<+4V7vvG_LW`geF3hnhZ^8Dm1O> z(2Qn6vziU<(yma6c8BIP7n;|6Xh931MJ$=1D&u)0Q>9}q=uG^05j^o;L zTz4JUJ;!z53AHMF;NhX;dgQnsJFX{=>#5^<=D40at{0B$r4wpa_R7O+$Mwc>y>(pg z9M^lt^}z{MD*Nc+ljHjAxV|{9ua4`R_i(B!%vS-q2FP_lZUAx4>=fZPXuya!AV0eJ+-V?dq& z@)VF~fIJ7}1t2d0c?HO8i2Tuc!~7PIcYwTy$e-sA%pU>y1juJVz5wzSkZ*u|2jmAJ zKLPm#+fQ=pImyG408#)*As|J76a!KMNGb4+O_MU_azHA;TbfiddGC`dq#6+axJeCC z3rHOx^?)=0(g;WsAkDzP{xoS}<_21kHbB||=>Vh?kS;*F0qFsx7mz+c`T-dLWG5hl RfD8dL49Ex|qkxP-{0}Hn##jIV literal 0 HcmV?d00001 diff --git a/addchain/35c748c2f8a21d58c760b80d94292763445b3e601ea271e3de6c45f741290002e16ba88600000010a1180000000000 b/addchain/35c748c2f8a21d58c760b80d94292763445b3e601ea271e3de6c45f741290002e16ba88600000010a1180000000000 new file mode 100644 index 0000000000000000000000000000000000000000..b701f7bef9834b7c19632ef018d4a156c2fa6e2a GIT binary patch literal 3461 zcmXBV0c6$v8o=@2^WW?y-6Wap%}gelnIuVOW-{H(-brSXbdzqrM5*uPeiH)(b#HQF(VsmUR zu_d;Y*cw|)Oo?qJCS$V1_SjxxN9-uEGj^70SBc%RyTqQ@7Qrt}{8g&gSGgmy_#! zj^CwzArBXGa$U;FbvY;3m7H8xb8=nF$#p#^*NvRU^SPOaTREkw-_E>~lk09yu6sGT z?&suskdy0SPOe8exgO`_dXkgtX^z*s{wxpAb8@}N$@MZP*Q=aduXA#}$;tILC)c~2 zT<>#oeaOl6F(=ojoD#F6{y7g{a&mpm$@MKK*Y})UKXSZ*^`Ck8m6PjtPOe%`iCQ$c zRESnY8-Bdz9;oFfIf-eA>4+JKnTT1G#zWhkXCpcga}b?~F2r0!H{P3?d#9FnPZB+d zUPK>a0dA3+JE|6o5Q`B@X#QeLo%<03h(W{u^h32=07;%Jc<}YtVFCrj3XxS zX4c%DwOE5#i&%$PkJy0Nh}cAFyri3*w;;A6wjm~Qv(((pwY;B`*ooMM*p1kO*o)YQ z*pE1XIEXleI814LNRBukMI1vMN1UMf)|_-cg*c5kgE)&ghd7V8fVfC$d>Ah|Uq)O( zTt!?%T&MYV-f+H&xP`clZ}wW;alVVVhq#Y;fOv>_gm_HzRe9q46!8r49PtA2lIG96 za(<0?gLsR0hj@?pfcQxBGxy2)GvW*4E8-jCJK_i8C*l{)7worl<4;D_;8G!45p9Sm zG(Nf2ROe}k>4+JKnTT14b{by~)okYu#2iE?q6;w>(T$jgn2+e8@#R(ZI`<(KAQmDP zAr{m8nI+Ck5&eh(#2{h_u?#VcSdLhM7(t98#t_gm{d2f_RE}hIo#6fq02{g?NpZ@r~14#5=@$#0SJj#3#gOn(x{d z=dXxwi0_CWh@XgGh~J1B87&QsFQ1l5x027brOjyyVk%-9B0r}s)5Q$LOvEfiJ7PAX z12G5DiRePiMRX(PA?71`5WR>#!~(=Z#3ICE#1h0(L_cBxF^CvKEJF+nlH?EedS2>uPxsf; zy-&YF`kZK6wQ+ge*grRIV)_LAk1d+4*RzW;uwo9a#0fv%$5eD9Oigj(1gB1M<_zb~ap3}&E^*}w*RFBn2Dff;=MFP7%*}D{o?Fvxar+|J=Z)O^l7PWeeN3 zv1=E5_AoKQfdd>m#E~N$JI09VY@OR4f+~U$gcZo1=UBA@X1UhC2TfSs?tzaWuY=I8CCFDC7-Pd z<&=x0I#i*WP?cO+)p7JCtARti z+IY?w&spO+XSnU@c^@tq&qd?8WIUIR=Zf)MHJ)q6bKQ7u7|%@;YEpX3hug+;$9V1< z&pqS0Z#)l-=b`aDGM>jK)S~o>4^NHfnejX~o)^aR(s*7O&uim(V?1w-=bb5julGKD zFrJUb^T~KV8_yTx`D#4hjOV)vwJZJM!%yS+Wjw!)r(i+_73Gp3kwKyaL(QHn=Taof zkSIr@0*Oi_s*uPbQH`NmPYq|HmZ(Fb9*G7d8j)y1f>+Z_v>?%nL>m(ANNho(1Bp%~ zx{&Bbq6hhXD)62w_+4j-ZAkPX(T~Ic5`#z#Au)`^2oj?h#g{q8c^ruyNK7CxiNq8V z(@4x9F^j|;67v|vpL!?f1tb=cSVAI?#4-{qNUS2UhWx22@J{Dm?&0BmNUS5Vfl>T@ zIl%cK5{HmDjKmQnjv{dkiQ`C|K;k44r;s>}#2F;cB5@9h^GIAk;vy24khqM*6(p`A zaSe&<{4~hFoJV4?h5|5C0jQlSs=n3biNIXO0ITA0Bc!|U- zBwi!&28p*wyu&EIJ>PTwfW${6J|XcLi7!ZeMdBM0-;wx%#7`uCA@LiD;)f$C$|XS} zgG31uStLr4C_|zgi3%htk*Go?%nL>m(A WNNho(1Bp%~x{&Bbq6djyjQ;_h^t?I% literal 0 HcmV?d00001 diff --git a/addchain/54aaaaab b/addchain/54aaaaab new file mode 100644 index 0000000000000000000000000000000000000000..9a8419e287a4d5b0f3056f6dffb8fe0081f352fe GIT binary patch literal 234 zcmWlP(MkeQ00n2RVj&@m$RaAsA|{K7h=_!Uh=^1#`U^h!6oo%v^-q1@cK2oA%$cu!gz*NN7}};SVqt8rOJeLKC5!a-m60hAOlr zG^MFXwuYuP9h%WhXjZeKIn9OUH6PlhZK3Vj9$L@>H?bqMsKrQjg_g7w$}1mQ)^cdK zc8B(8PiRFep;fJhDz%r@&DONAR$S|K71sUB1CHyU<2vNH4m++Rj_au7I_88*RXFb9 zgyTBtxK25)(~j$m<2vhb>B2b==N;Dtheaz~^l-^>Z8)yWj_Zo!y6U*DIj-wYcIg`) zZaS`8j_bDLy5qR+I<9+8B!&Cd2afBZ<9g({9y_ilj_ax8dgkzb6rOu{;kaHpu2+uh zwc~o@WFPFUhj)(az2o}eWHQbwTwfj6H^=qeas6;yKb>rKetAfpP^t_L z2_Pkalmb!)NI4)CfK&pvl(HdG?*@Zx0;C4GY|8dXy+I684@d(bjes-((hNuoAg#bU zrfi|qo5&y?fOJCfmb#d`0qFsx7mz+c`l0wY1I&Yf3;{9>$Os^#fQ$h$4#kf;!JGqR z5|Ax`OaZbLkZC|>AhHFVWu60M9wJHEtf{xFK^6en0mvdCy8u}NBoD|ku+>vGbm}c_ zkQG2y0oe=4en8d$SqJ0*gsNNznGXSS7?2}?90lYUAjg46KGg~4lYpFp;)0%LJ_E>E zK+XYj9*_%wT!iA2a*25ZSiZ|lR{*&R$TdK&19Ah9n}FN`{S^L}Uk0mx54egTsGSdxrv_4#L-CMAHB0#XM4K9X{#3PAi6B$Y@NAk~0u0;C3z zTFCA!sbj7O&e_1!2uKqk&49E3(h5i$Anky30MZFa7a-k$^Z?QeNFN~mfD8aK2*?m1 U!+?wcG788TAme~c0Fs0FAL8)5N&o-= literal 0 HcmV?d00001 diff --git a/addchain/7 b/addchain/7 new file mode 100644 index 0000000000000000000000000000000000000000..c1410c6d13353d0351fa753eb3fe120b9d7c4f57 GIT binary patch literal 68 zcmWgp-^j$s$R1FXpI(%h%lN;Ef$@I>1A}xuGb1CDe*uWY2vp$7$il$L=mjJh7zBWd QSQwa?7#LZAd?q#q072&rs{jB1 literal 0 HcmV?d00001 diff --git a/addchain/7fffffff b/addchain/7fffffff new file mode 100644 index 0000000000000000000000000000000000000000..2702c2bd601e9bdec1d5ecace2b67f582b0c5adf GIT binary patch literal 232 zcmWlQO=`kW00w7XLn|U8Qi50!2~k8uL_|bHL_};idIeWq6-zGApDXo%>C0wdKITiy zpP*0I;{IOTJ}iH+{DzmW2Mw3cN{qp)3HlZZACJb1vPM?87LXV3ft1hW{5 literal 0 HcmV?d00001 diff --git a/addchain/7fffffff80000000 b/addchain/7fffffff80000000 new file mode 100644 index 0000000000000000000000000000000000000000..3f6891cde4118c5c70424386a705be833d3be08c GIT binary patch literal 393 zcmXAl{YQfV6h_ZkS((fvGizoh$z&$UWRf+h%$k~+B$cVms(DQ^Ss(hld)r&TT+e+R zmwVFTXG|B`!Sj7^^Jw^m;Rmd~&uQ#*6fMqxW9QM6*@Pd@XV?L;7|ut1+<250F<}Ci zT*9PDOqq(hWn6Iu)21U94HdJ@;_meXLu@hK=anAs%_e?12+(+QgPEY}>{&&#+?$yLPc>4==pH zOE2-tE4=m^Z@tC7eZ2DyAAG=p0~|WUC!cWS2m=EgJH{7Z@YPqGIKemHaOyNN{O2|N K`uF{9_{}eE3pU~a literal 0 HcmV?d00001 diff --git a/addchain/887f22fd4d1b5f85a1612fe51b079a9239a3cf232d7e1cf5e00000000000000 b/addchain/887f22fd4d1b5f85a1612fe51b079a9239a3cf232d7e1cf5e00000000000000 new file mode 100644 index 0000000000000000000000000000000000000000..a7f5393649459ac9e038062a83aa0da27a3a4e7a GIT binary patch literal 2254 zcmXAp0c4eX9EN}IcW3vQnVDl|cP2A4Gcz+YGcz-@JF`2JOlEdxb|<^LGcz-@+nppy zl4O!3Ns=TsSCN+hc)f{S3OQ=QPUqSG}P=^@aM?9~#g=Xi$Tp3JryZH5?kzNN7}}p)rkxc4}v6mv)85 zHO`0F9h%TYXi}4*DNTi@H65DKOlVfKp*hWksr(79#f7nkiGNp-f?|!Tpu0RC&%^KVXLw)9= z3m~n4v;oo%NC&VPDQ7HI7a-k$^Z?QeNFN~mfD8aK2*?mb;bRXoj{q_X$QZCcDd#fv z$u!6~AiDvX0Av!7DL|%S`(Dm4&jKd{eT<*067bM+od|k zd>)VsfLsLR5+IiWxdO;lK&}CD9grKaz0)_DZvk=}kUN0f1>_z?;UL^+egMcrKpp|| z7?3Bhy;)D0p8@h5kQacw1mqPUuK{@j$Xh_(0rDP@4}g3G*RS3tf2@*R*L zfcylc@MB2|uq1#K0a6S|4v-Q+N&zVYq#Te6K=Oc80#XG?H6VVZk{YBIkR5>30pbTH tsYe4=m{_ihR^5-~*{04t0FQhg*1qK&-pm-@w(vgy6Ew`!HW%k;m(?$LonFRI2o;k7pjQEsxi>$LqPr>xIYbrN`@) zCsd^LwU0L*ueTnrcOI|z9mVUDG<{jW zm;-SFk$p|(xfehzf>;8v4B{k+Q;6&vXN7we#Ay&`K&*jS2XPj}IS}Wu^HsXQeG$YZ z5SKw*0dWoC+^Q6zJT}&;v0zX;Qz3k zesKQ;k^OQc86F9UJP`RH3Xr{El0xoXAa;W&0^z?YDJDull!7Qj@be_u!(9%7-`Pu4 zfY=A362yKG2S6M|_VXh-#9amAFo+`{szKC%s73GtE2-nI2hjkc5kwP+W)Lmd`9NB^ z+d#B~=m60Pq6*SI_?jaDvAdZ4K24V!nD2Oo-;|PB8CKKF~ zAf^yWE}7<<0Wk|=4#Wu%^B@*LEP_}9u?*rQc=xBcRzR$RI1Sq1*Z{E!;x>po$bP^ice(F@xDVn1h=(8^ hfp`q!35cg4o`Ki`u?^xmh!-GUf_MeuHHbHe{{b9Zp^pFn literal 0 HcmV?d00001 diff --git a/addchain/d555555 b/addchain/d555555 new file mode 100644 index 0000000000000000000000000000000000000000..47ff9dfbee60e19c927ac66513e633f5df60b9ea GIT binary patch literal 214 zcmWlR%?d$b00n10LXsrigoGqXk|as8Wy332S&6)WpEvQO*Znr9&YbBa=_hFM{JdYE zmz(Jq(>JtVISr>rEM~&NJbKI$(qCrvBMyWN7c5}O5|%ATT*0bUtXadlb!^zc!~~l* z#cV=dGkC~ZCW@ct)c4u~HW+pScGrKdZJIBn->~=Fr zk|arzBuSDalO#!!BuSDaNs=T|eW; z-xtd7jri@~U!>&EWrqBQKU5OZkk5!**|y)7)9;Zak@)pQrJ*vFag;|=5h_t7FIRD- zLgiSc(!8N2RK<~~E>x}BP=y+pjm#!~+Z-xYCX`l7D5X|r8&_#(+EVHWb#Qd5Gt{N7 zP`A26J?aVdsyEc9zEHpVL+u&}4Qeoa`$M5&4TnZF5*pQLXiQ_FagB#2G!dHAWT-{E zLQ|RwO=~(dqnXgGW-|}nw9oGTJb$92tdZ9Ac6<*$3(a9lSX*Dc3& z+i~4-Tz4JUJ;!z5aXoNCjmkgtc;vVqJFX{=>#5^<=D40at{0B$r4y=E{*}jT$Mwc> zy>(pg9M^lt^}%s{bX=dDNb;YpUmVw0$Mwx|eRo_x9M@0Bm2*Nl72rq!DFLJukTO8Z z0jYpcy{nR41xN~zYCzI})BsWoNF5+trygklq!D-|IsSce{&)R1f&y?Een{kUogQ-Sx8v02u^i2#{ewMgSQFWDJmTKqdg0gectRF7^~4 z(}2tXG7HEYAoGAM0I~?7Cf5>s4_wR@9sVO10Wv(`2@&kK)wL-6_9U$e23!Yez1Q6QuwhX1vnBw zN&qPZqzsU9C|r&&-ds`%NEPr^oJ&&dYCzI})BsWoNF5;cfHVNo2uKqk&46S8X#u1a qkTyWt0qFo_2Ov8E=>((;kZwSF0OF0Qnn{u* zNs=Tj_31xKHt6PkMsWC^E<1|_9xQsqq%?o&i(a| zvW-x-FJi}kze&lT%M9`bf2bg&A+Hf>(Uvbu)f`C@NkJrqkragrRLrF%p+c3ilrffL z6JJTQAk?Itp+OCXZ+<8=tl`jzMna<+4V7vvG_LW`geF3hnhZ^8Dm1O> z(2Qn6vziU<(yma6c8BIP7n;|6Xh931MJ$=1D&u)0Q>9}q=uG^05j^o;L zTz4JUJ;!z53AHMF;NhX;dgQnsJFX{=>#5^<=D40at{0B$r4wpa_R7O+$Mwc>y>(pg z9M^lt^}z{MD*Nc+ljHjAxV|{9ua4`R_i(B!%vS-q2FP_lZUAx4>=fZPXuya!AV0eJ+-V?dq& z@)VF~fIJ7}1t2d0c?HO8i2Tuc!~7PIcYwTy$e-sA%pU>y1juJVz5wzSkZ*u|2jmAJ zKLPm#+fQ=pImyG408#)*As|J76a!KMNGb4+O_MU_azHA;TbfiddGC`dq#6+axJeCC z3rHOx^?)=0(g;WsAkDzP{xoS}<_21kHbB||=>Vh?kS;*F0qFsx7mz+c`T-dLWG5hl RfD8dL49Ex|qkxP-{0}Hn##jIV literal 0 HcmV?d00001 diff --git a/internal/generator/addchain/35c748c2f8a21d58c760b80d94292763445b3e601ea271e3de6c45f741290002e16ba88600000010a1180000000000 b/internal/generator/addchain/35c748c2f8a21d58c760b80d94292763445b3e601ea271e3de6c45f741290002e16ba88600000010a1180000000000 new file mode 100644 index 0000000000000000000000000000000000000000..b701f7bef9834b7c19632ef018d4a156c2fa6e2a GIT binary patch literal 3461 zcmXBV0c6$v8o=@2^WW?y-6Wap%}gelnIuVOW-{H(-brSXbdzqrM5*uPeiH)(b#HQF(VsmUR zu_d;Y*cw|)Oo?qJCS$V1_SjxxN9-uEGj^70SBc%RyTqQ@7Qrt}{8g&gSGgmy_#! zj^CwzArBXGa$U;FbvY;3m7H8xb8=nF$#p#^*NvRU^SPOaTREkw-_E>~lk09yu6sGT z?&suskdy0SPOe8exgO`_dXkgtX^z*s{wxpAb8@}N$@MZP*Q=aduXA#}$;tILC)c~2 zT<>#oeaOl6F(=ojoD#F6{y7g{a&mpm$@MKK*Y})UKXSZ*^`Ck8m6PjtPOe%`iCQ$c zRESnY8-Bdz9;oFfIf-eA>4+JKnTT1G#zWhkXCpcga}b?~F2r0!H{P3?d#9FnPZB+d zUPK>a0dA3+JE|6o5Q`B@X#QeLo%<03h(W{u^h32=07;%Jc<}YtVFCrj3XxS zX4c%DwOE5#i&%$PkJy0Nh}cAFyri3*w;;A6wjm~Qv(((pwY;B`*ooMM*p1kO*o)YQ z*pE1XIEXleI814LNRBukMI1vMN1UMf)|_-cg*c5kgE)&ghd7V8fVfC$d>Ah|Uq)O( zTt!?%T&MYV-f+H&xP`clZ}wW;alVVVhq#Y;fOv>_gm_HzRe9q46!8r49PtA2lIG96 za(<0?gLsR0hj@?pfcQxBGxy2)GvW*4E8-jCJK_i8C*l{)7worl<4;D_;8G!45p9Sm zG(Nf2ROe}k>4+JKnTT14b{by~)okYu#2iE?q6;w>(T$jgn2+e8@#R(ZI`<(KAQmDP zAr{m8nI+Ck5&eh(#2{h_u?#VcSdLhM7(t98#t_gm{d2f_RE}hIo#6fq02{g?NpZ@r~14#5=@$#0SJj#3#gOn(x{d z=dXxwi0_CWh@XgGh~J1B87&QsFQ1l5x027brOjyyVk%-9B0r}s)5Q$LOvEfiJ7PAX z12G5DiRePiMRX(PA?71`5WR>#!~(=Z#3ICE#1h0(L_cBxF^CvKEJF+VY@OR4f+~U$gcZo1=UBA@X1UhC2TfSs?tzaWuY=I8CCFDC7-Pd z<&=x0I#i*WP?cO+)p7JCtARti z+IY?w&spO+XSnU@c^@tq&qd?8WIUIR=Zf)MHJ)q6bKQ7u7|%@;YEpX3hug+;$9V1< z&pqS0Z#)l-=b`aDGM>jK)S~o>4^NHfnejX~o)^aR(s*7O&uim(V?1w-=bb5julGKD zFrJUb^T~KV8_yTx`D#4hjOV)vwJZJM!%yS+Wjw!)r(i+_73Gp3kwKyaL(QHn=Taof zkSIr@0*Oi_s*uPbQH`NmPYq|HmZ(Fb9*G7d8j)y1f>+Z_v>?%nL>m(ANNho(1Bp%~ zx{&Bbq6hhXD)62w_+4j-ZAkPX(T~Ic5`#z#Au)`^2oj?h#g{q8c^ruyNK7CxiNq8V z(@4x9F^j|;67v|vpL!?f1tb=cSVAI?#4-{qNUS2UhWx22@J{Dm?&0BmNUS5Vfl>T@ zIl%cK5{HmDjKmQnjv{dkiQ`C|K;k44r;s>}#2F;cB5@9h^GIAk;vy24khqM*6(p`A zaSe&<{4~hFoJV4?h5|5C0jQlSs=n3biNIXO0ITA0Bc!|U- zBwi!&28p*wyu&EIJ>PTwfW${6J|XcLi7!ZeMdBM0-;wx%#7`uCA@LiD;)f$C$|XS} zgG31uStLr4C_|zgi3%htk*Go?%nL>m(A WNNho(1Bp%~x{&Bbq6djyjQ;_h^t?I% literal 0 HcmV?d00001 diff --git a/internal/generator/addchain/60c89ce5c263405370a08b6d0302b0ba5067d090f372e12287c3eb27e000000 b/internal/generator/addchain/60c89ce5c263405370a08b6d0302b0ba5067d090f372e12287c3eb27e000000 new file mode 100644 index 0000000000000000000000000000000000000000..b69e9b6b27053d660e16d0728de0fdf7857d6647 GIT binary patch literal 2274 zcmXAq0c2Hs9LIm(^JZ^mW+pRhW@ct@W@ct)W@cvgX7;YhWM=jzy~*m$HOWl%W|AaH zk|arzOp+u?k|arzBuSDaNs=VVx$pZq*S??g{rqu!gz*NN7}};SVqt8rOJeLKC5!a-m60hAOlr zG^MFXwuYuP9h%WhXjZeKIn9OUH6PlhZK3Vj9$L@>H?bqMsKrQjg_g7w$}1mQ)^cdK zc8B(8PiRFep;fJhDz%r@&DONAR$S|K71sUB1CHyU<2vNH4m++Rj_au7I_88*RXFb9 zgyTBtxK25)(~j$m<2vhb>B2b==N;Dtheaz~^l-^>Z8)yWj_Zo!y6U*DIj-wYcIg`) zZaS`8j_bDLy5qR+I<9+8B!&Cd2afBZ<9g({9y_ilj_ax8dgkzb6rOu{;kaHpu2+uh zwc~o@WFPFUhj)(az2o}eWHQbwTwfj6H^=qeas6;yKb>rKetAfpP^t_L z2_Pkalmb!)NI4)CfK&pvl(HdG?*@Zx0;C4GY|8dXy+I684@d(bjes-((hNuoAg#bU zrfi|qo5&y?fOJCfmb#d`0qFsx7mz+c`l0wY1I&Yf3;{9>$Os^#fQ$h$4#kf;!JGqR z5|Ax`OaZbLkZC|>AhHFVWu60M9wJHEtf{xFK^6en0mvdCy8u}NBoD|ku+>vGbm}c_ zkQG2y0oe=4en8d$SqJ0*gsNNznGXSS7?2}?90lYUAjg46KGg~4lYpFp;)0%LJ_E>E zK+XYj9*_%wT!iA2a*25ZSiZ|lR{*&R$TdK&19Ah9n}FN`{S^L}Uk0mx54egTsGSdxrv_4#L-CMAHB0#XM4K9X{#3PAi6B$Y@NAk~0u0;C3z zTFCA!sbj7O&e_1!2uKqk&49E3(h5i$Anky30MZFa7a-k$^Z?QeNFN~mfD8aK2*?m1 U!+?wcG788TAme~c0Fs0FAL8)5N&o-= literal 0 HcmV?d00001 diff --git a/internal/generator/addchain/887f22fd4d1b5f85a1612fe51b079a9239a3cf232d7e1cf5e00000000000000 b/internal/generator/addchain/887f22fd4d1b5f85a1612fe51b079a9239a3cf232d7e1cf5e00000000000000 new file mode 100644 index 0000000000000000000000000000000000000000..a7f5393649459ac9e038062a83aa0da27a3a4e7a GIT binary patch literal 2254 zcmXAp0c4eX9EN}IcW3vQnVDl|cP2A4Gcz+YGcz-@JF`2JOlEdxb|<^LGcz-@+nppy zl4O!3Ns=TsSCN+hc)f{S3OQ=QPUqSG}P=^@aM?9~#g=Xi$Tp3JryZH5?kzNN7}}p)rkxc4}v6mv)85 zHO`0F9h%TYXi}4*DNTi@H65DKOlVfKp*hWksr(79#f7nkiGNp-f?|!Tpu0RC&%^KVXLw)9= z3m~n4v;oo%NC&VPDQ7HI7a-k$^Z?QeNFN~mfD8aK2*?mb;bRXoj{q_X$QZCcDd#fv z$u!6~AiDvX0Av!7DL|%S`(Dm4&jKd{eT<*067bM+od|k zd>)VsfLsLR5+IiWxdO;lK&}CD9grKaz0)_DZvk=}kUN0f1>_z?;UL^+egMcrKpp|| z7?3Bhy;)D0p8@h5kQacw1mqPUuK{@j$Xh_(0rDP@4}g3G*RS3tf2@*R*L zfcylc@MB2|uq1#K0a6S|4v-Q+N&zVYq#Te6K=Oc80#XG?H6VVZk{YBIkR5>30pbTH tsYe4=m{_ihR^5-~*{04t0FQhg*1qK&-pm-@w(vgy6Ew`!HW%k;m(?$LonFRI2o;k7pjQEsxi>$LqPr>xIYbrN`@) zCsd^LwU0L*ueTnrcOI|z9mVUDG<{jW zm;-SFk$p|(xfehzf>;8v4B{k+Q;6&vXN7we#Ay&`K&*jS2XPj}IS}Wu^HsXQeG$YZ z5SKw*0dWoC+^Q6zJT}&;v0zX;Qz3k zesKQ;k^OQc86F9UJP`RH3Xr{El0xoXAa;W&0^z?YDJDull!7Qj@be_u!(9%7-`Pu4 zfY=A362yKG2S6M|_VXh-#9amAFo+`{szKC%s73GtE2-nI2hjkc5kwP+W)Lmd`9NB^ z+d#B~=m60Pq6*SI_?jaDvAdZ4K24V!nD2Oo-;|PB8CKKF~ zAf^yWE}7<<0Wk|=4#Wu%^B@*LEP_}9u?*rQc=xBcRzR$RI1Sq1*Z{E!;x>po$bP^ice(F@xDVn1h=(8^ hfp`q!35cg4o`Ki`u?^xmh!-GUf_MeuHHbHe{{b9Zp^pFn literal 0 HcmV?d00001 diff --git a/internal/generator/addchain/e7db4ea6533afa906673b0101343b00aa77b4805fffcb7fdfffffffe0000000 b/internal/generator/addchain/e7db4ea6533afa906673b0101343b00aa77b4805fffcb7fdfffffffe0000000 new file mode 100644 index 0000000000000000000000000000000000000000..fdfff202060ffcdd262faf658980a71adae190c9 GIT binary patch literal 2284 zcmXAq0c4eX9EN}IcV~BIW{x>#cV=dGkC~ZCW@ct)c4u~HW+pScGrKdZJIBn->~=Fr zk|arzBuSDalO#!!BuSDaNs=T|eW; z-xtd7jri@~U!>&EWrqBQKU5OZkk5!**|y)7)9;Zak@)pQrJ*vFag;|=5h_t7FIRD- zLgiSc(!8N2RK<~~E>x}BP=y+pjm#!~+Z-xYCX`l7D5X|r8&_#(+EVHWb#Qd5Gt{N7 zP`A26J?aVdsyEc9zEHpVL+u&}4Qeoa`$M5&4TnZF5*pQLXiQ_FagB#2G!dHAWT-{E zLQ|RwO=~(dqnXgGW-|}nw9oGTJb$92tdZ9Ac6<*$3(a9lSX*Dc3& z+i~4-Tz4JUJ;!z5aXoNCjmkgtc;vVqJFX{=>#5^<=D40at{0B$r4y=E{*}jT$Mwc> zy>(pg9M^lt^}%s{bX=dDNb;YpUmVw0$Mwx|eRo_x9M@0Bm2*Nl72rq!DFLJukTO8Z z0jYpcy{nR41xN~zYCzI})BsWoNF5+trygklq!D-|IsSce{&)R1f&y?Een{kUogQ-Sx8v02u^i2#{ewMgSQFWDJmTKqdg0gectRF7^~4 z(}2tXG7HEYAoGAM0I~?7Cf5>s4_wR@9sVO10Wv(`2@&kK)wL-6_9U$e23!Yez1Q6QuwhX1vnBw zN&qPZqzsU9C|r&&-ds`%NEPr^oJ&&dYCzI})BsWoNF5;cfHVNo2uKqk&46S8X#u1a qkTyWt0qFo_2Ov8E=>((;kZwSF0O Date: Mon, 20 Apr 2026 16:54:29 -0400 Subject: [PATCH 2/8] refactor: lazy-initializing subgroup parameters behind sync.Once --- ecc/bls12-377/twistededwards/curve.go | 6 +++--- ecc/bls12-377/twistededwards/subgroup.go | 1 + ecc/bls12-381/twistededwards/curve.go | 6 +++--- ecc/bls12-381/twistededwards/subgroup.go | 1 + ecc/bls24-315/twistededwards/curve.go | 6 +++--- ecc/bls24-315/twistededwards/subgroup.go | 1 + ecc/bls24-317/twistededwards/curve.go | 6 +++--- ecc/bls24-317/twistededwards/subgroup.go | 1 + ecc/bn254/twistededwards/curve.go | 6 +++--- ecc/bn254/twistededwards/subgroup.go | 1 + ecc/bw6-633/twistededwards/curve.go | 6 +++--- ecc/bw6-633/twistededwards/subgroup.go | 1 + ecc/bw6-761/twistededwards/curve.go | 6 +++--- ecc/bw6-761/twistededwards/subgroup.go | 1 + internal/generator/edwards/template/curve.go.tmpl | 6 +++--- internal/generator/edwards/template/subgroup.go.tmpl | 1 + 16 files changed, 32 insertions(+), 24 deletions(-) diff --git a/ecc/bls12-377/twistededwards/curve.go b/ecc/bls12-377/twistededwards/curve.go index 4f1314bb95..3304566c0d 100644 --- a/ecc/bls12-377/twistededwards/curve.go +++ b/ecc/bls12-377/twistededwards/curve.go @@ -48,8 +48,9 @@ func GetEdwardsCurve() CurveParams { } var ( - initOnce sync.Once - curveParams CurveParams + initOnce sync.Once + curveParams CurveParams + subgroupInitOnce sync.Once ) func initCurveParams() { @@ -60,7 +61,6 @@ func initCurveParams() { curveParams.Base.X.SetString("717051916204163000937139483451426116831771857428389560441264442629694842243") curveParams.Base.Y.SetString("882565546457454111605105352482086902132191855952243170543452705048019814192") - initCofactorSubgroupParams() } // mulByA multiplies fr.Element by curveParams.A diff --git a/ecc/bls12-377/twistededwards/subgroup.go b/ecc/bls12-377/twistededwards/subgroup.go index dbbad81835..341c139578 100644 --- a/ecc/bls12-377/twistededwards/subgroup.go +++ b/ecc/bls12-377/twistededwards/subgroup.go @@ -314,6 +314,7 @@ func (p *PointAffine) IsInSubGroup() bool { } initOnce.Do(initCurveParams) + subgroupInitOnce.Do(initCofactorSubgroupParams) var r weierstrassPointAffine if !mapPointToWeierstrass(p, &r) { diff --git a/ecc/bls12-381/twistededwards/curve.go b/ecc/bls12-381/twistededwards/curve.go index 40bf28643b..149197d8ba 100644 --- a/ecc/bls12-381/twistededwards/curve.go +++ b/ecc/bls12-381/twistededwards/curve.go @@ -52,8 +52,9 @@ func GetEdwardsCurve() CurveParams { } var ( - initOnce sync.Once - curveParams CurveParams + initOnce sync.Once + curveParams CurveParams + subgroupInitOnce sync.Once ) func initCurveParams() { @@ -64,7 +65,6 @@ func initCurveParams() { curveParams.Base.X.SetString("23426137002068529236790192115758361610982344002369094106619281483467893291614") curveParams.Base.Y.SetString("39325435222430376843701388596190331198052476467368316772266670064146548432123") - initCofactorSubgroupParams() } // mulByA multiplies fr.Element by curveParams.A diff --git a/ecc/bls12-381/twistededwards/subgroup.go b/ecc/bls12-381/twistededwards/subgroup.go index a9d7e2d4f9..b33f65b4ee 100644 --- a/ecc/bls12-381/twistededwards/subgroup.go +++ b/ecc/bls12-381/twistededwards/subgroup.go @@ -401,6 +401,7 @@ func (p *PointAffine) IsInSubGroup() bool { } initOnce.Do(initCurveParams) + subgroupInitOnce.Do(initCofactorSubgroupParams) var r weierstrassPointAffine if !mapPointToWeierstrass(p, &r) { diff --git a/ecc/bls24-315/twistededwards/curve.go b/ecc/bls24-315/twistededwards/curve.go index 6f5e95ecf0..55b87c8821 100644 --- a/ecc/bls24-315/twistededwards/curve.go +++ b/ecc/bls24-315/twistededwards/curve.go @@ -52,8 +52,9 @@ func GetEdwardsCurve() CurveParams { } var ( - initOnce sync.Once - curveParams CurveParams + initOnce sync.Once + curveParams CurveParams + subgroupInitOnce sync.Once ) func initCurveParams() { @@ -64,7 +65,6 @@ func initCurveParams() { curveParams.Base.X.SetString("750878639751052675245442739791837325424717022593512121860796337974109802674") curveParams.Base.Y.SetString("1210739767513185331118744674165833946943116652645479549122735386298364723201") - initCofactorSubgroupParams() } // mulByA multiplies fr.Element by curveParams.A diff --git a/ecc/bls24-315/twistededwards/subgroup.go b/ecc/bls24-315/twistededwards/subgroup.go index da16f8af5c..9925a3869e 100644 --- a/ecc/bls24-315/twistededwards/subgroup.go +++ b/ecc/bls24-315/twistededwards/subgroup.go @@ -440,6 +440,7 @@ func (p *PointAffine) IsInSubGroup() bool { } initOnce.Do(initCurveParams) + subgroupInitOnce.Do(initCofactorSubgroupParams) var r weierstrassPointAffine if !mapPointToWeierstrass(p, &r) { diff --git a/ecc/bls24-317/twistededwards/curve.go b/ecc/bls24-317/twistededwards/curve.go index f6e7d7517f..40af56099e 100644 --- a/ecc/bls24-317/twistededwards/curve.go +++ b/ecc/bls24-317/twistededwards/curve.go @@ -52,8 +52,9 @@ func GetEdwardsCurve() CurveParams { } var ( - initOnce sync.Once - curveParams CurveParams + initOnce sync.Once + curveParams CurveParams + subgroupInitOnce sync.Once ) func initCurveParams() { @@ -64,7 +65,6 @@ func initCurveParams() { curveParams.Base.X.SetString("4348505656527095883506785370890963704100065639426869666063106978260788240233") curveParams.Base.Y.SetString("1929349327278552762783636859845493911537170411830425720219700276810167091201") - initCofactorSubgroupParams() } // mulByA multiplies fr.Element by curveParams.A diff --git a/ecc/bls24-317/twistededwards/subgroup.go b/ecc/bls24-317/twistededwards/subgroup.go index 6eba5ef044..d5a0a84cd3 100644 --- a/ecc/bls24-317/twistededwards/subgroup.go +++ b/ecc/bls24-317/twistededwards/subgroup.go @@ -402,6 +402,7 @@ func (p *PointAffine) IsInSubGroup() bool { } initOnce.Do(initCurveParams) + subgroupInitOnce.Do(initCofactorSubgroupParams) var r weierstrassPointAffine if !mapPointToWeierstrass(p, &r) { diff --git a/ecc/bn254/twistededwards/curve.go b/ecc/bn254/twistededwards/curve.go index 560d935879..757a18cfab 100644 --- a/ecc/bn254/twistededwards/curve.go +++ b/ecc/bn254/twistededwards/curve.go @@ -52,8 +52,9 @@ func GetEdwardsCurve() CurveParams { } var ( - initOnce sync.Once - curveParams CurveParams + initOnce sync.Once + curveParams CurveParams + subgroupInitOnce sync.Once ) func initCurveParams() { @@ -64,7 +65,6 @@ func initCurveParams() { curveParams.Base.X.SetString("9671717474070082183213120605117400219616337014328744928644933853176787189663") curveParams.Base.Y.SetString("16950150798460657717958625567821834550301663161624707787222815936182638968203") - initCofactorSubgroupParams() } // mulByA multiplies fr.Element by curveParams.A diff --git a/ecc/bn254/twistededwards/subgroup.go b/ecc/bn254/twistededwards/subgroup.go index e521fbf81d..a818017f56 100644 --- a/ecc/bn254/twistededwards/subgroup.go +++ b/ecc/bn254/twistededwards/subgroup.go @@ -451,6 +451,7 @@ func (p *PointAffine) IsInSubGroup() bool { } initOnce.Do(initCurveParams) + subgroupInitOnce.Do(initCofactorSubgroupParams) var r weierstrassPointAffine if !mapPointToWeierstrass(p, &r) { diff --git a/ecc/bw6-633/twistededwards/curve.go b/ecc/bw6-633/twistededwards/curve.go index a3d39e6f7c..11d4ad41fa 100644 --- a/ecc/bw6-633/twistededwards/curve.go +++ b/ecc/bw6-633/twistededwards/curve.go @@ -52,8 +52,9 @@ func GetEdwardsCurve() CurveParams { } var ( - initOnce sync.Once - curveParams CurveParams + initOnce sync.Once + curveParams CurveParams + subgroupInitOnce sync.Once ) func initCurveParams() { @@ -64,7 +65,6 @@ func initCurveParams() { curveParams.Base.X.SetString("37635937024655419978837220647164498012335808680404874556501960268316961933409049243153117555100") curveParams.Base.Y.SetString("23823085625708063001015413934245381846960101450148849601038571303382730455875805408244170280142") - initCofactorSubgroupParams() } // mulByA multiplies fr.Element by curveParams.A diff --git a/ecc/bw6-633/twistededwards/subgroup.go b/ecc/bw6-633/twistededwards/subgroup.go index 536e6453c8..ec28422ad5 100644 --- a/ecc/bw6-633/twistededwards/subgroup.go +++ b/ecc/bw6-633/twistededwards/subgroup.go @@ -499,6 +499,7 @@ func (p *PointAffine) IsInSubGroup() bool { } initOnce.Do(initCurveParams) + subgroupInitOnce.Do(initCofactorSubgroupParams) var r weierstrassPointAffine if !mapPointToWeierstrass(p, &r) { diff --git a/ecc/bw6-761/twistededwards/curve.go b/ecc/bw6-761/twistededwards/curve.go index fad03386d3..11728c5b93 100644 --- a/ecc/bw6-761/twistededwards/curve.go +++ b/ecc/bw6-761/twistededwards/curve.go @@ -52,8 +52,9 @@ func GetEdwardsCurve() CurveParams { } var ( - initOnce sync.Once - curveParams CurveParams + initOnce sync.Once + curveParams CurveParams + subgroupInitOnce sync.Once ) func initCurveParams() { @@ -64,7 +65,6 @@ func initCurveParams() { curveParams.Base.X.SetString("109887223397525145051017418760180386187632078445902299543670312117371514695798874370143656894667315818446285582389") curveParams.Base.Y.SetString("31146823455109675839494591101665406662142618451815824757336761504421066243585705807124836638254810186490790034654") - initCofactorSubgroupParams() } // mulByA multiplies fr.Element by curveParams.A diff --git a/ecc/bw6-761/twistededwards/subgroup.go b/ecc/bw6-761/twistededwards/subgroup.go index b44d13335d..6fcfaf5421 100644 --- a/ecc/bw6-761/twistededwards/subgroup.go +++ b/ecc/bw6-761/twistededwards/subgroup.go @@ -514,6 +514,7 @@ func (p *PointAffine) IsInSubGroup() bool { } initOnce.Do(initCurveParams) + subgroupInitOnce.Do(initCofactorSubgroupParams) var r weierstrassPointAffine if !mapPointToWeierstrass(p, &r) { diff --git a/internal/generator/edwards/template/curve.go.tmpl b/internal/generator/edwards/template/curve.go.tmpl index 46f7253d6f..fe1ecbaf2f 100644 --- a/internal/generator/edwards/template/curve.go.tmpl +++ b/internal/generator/edwards/template/curve.go.tmpl @@ -79,6 +79,9 @@ func GetEdwardsCurve() CurveParams { var ( initOnce sync.Once curveParams CurveParams + {{- if and (not .Split2Torsion) (or (eq .Cofactor "4") (eq .Cofactor "8"))}} + subgroupInitOnce sync.Once + {{- end}} ) @@ -95,9 +98,6 @@ func initCurveParams() { curveParams.t1.SetString("7467641132672931490026245929168323482429801851415215058808452942653048173085") curveParams.b.SetString("25465760566081946422412445027709227188579564747101592991722834452325077642517") {{- end}} - {{- if and (not .Split2Torsion) (or (eq .Cofactor "4") (eq .Cofactor "8"))}} - initCofactorSubgroupParams() - {{- end}} {{- if .HasEndomorphism}} curveParams.endo[0].SetString("{{.Endo0}}") diff --git a/internal/generator/edwards/template/subgroup.go.tmpl b/internal/generator/edwards/template/subgroup.go.tmpl index 68df6f4b1d..6f4ebb7deb 100644 --- a/internal/generator/edwards/template/subgroup.go.tmpl +++ b/internal/generator/edwards/template/subgroup.go.tmpl @@ -230,6 +230,7 @@ func (p *PointAffine) IsInSubGroup() bool { } initOnce.Do(initCurveParams) + subgroupInitOnce.Do(initCofactorSubgroupParams) var r weierstrassPointAffine if !mapPointToWeierstrass(p, &r) { From 2b92306d5365ab90a6baa01606a8904729a2abb2 Mon Sep 17 00:00:00 2001 From: Youssef El Housni Date: Mon, 20 Apr 2026 17:03:28 -0400 Subject: [PATCH 3/8] refactor: move subgroup data out of CurveParams --- ecc/bls12-377/twistededwards/curve.go | 12 ---- ecc/bls12-377/twistededwards/subgroup.go | 43 +++++++++---- ecc/bls12-381/twistededwards/curve.go | 16 ----- ecc/bls12-381/twistededwards/subgroup.go | 55 +++++++++++------ ecc/bls24-315/twistededwards/curve.go | 16 ----- ecc/bls24-315/twistededwards/subgroup.go | 55 +++++++++++------ ecc/bls24-317/twistededwards/curve.go | 16 ----- ecc/bls24-317/twistededwards/subgroup.go | 55 +++++++++++------ ecc/bn254/twistededwards/curve.go | 16 ----- ecc/bn254/twistededwards/subgroup.go | 55 +++++++++++------ ecc/bw6-633/twistededwards/curve.go | 16 ----- ecc/bw6-633/twistededwards/subgroup.go | 55 +++++++++++------ ecc/bw6-761/twistededwards/curve.go | 16 ----- ecc/bw6-761/twistededwards/subgroup.go | 55 +++++++++++------ .../generator/edwards/template/curve.go.tmpl | 20 ------ .../edwards/template/subgroup.go.tmpl | 61 +++++++++++++------ 16 files changed, 300 insertions(+), 262 deletions(-) diff --git a/ecc/bls12-377/twistededwards/curve.go b/ecc/bls12-377/twistededwards/curve.go index 3304566c0d..928591a00e 100644 --- a/ecc/bls12-377/twistededwards/curve.go +++ b/ecc/bls12-377/twistededwards/curve.go @@ -18,18 +18,6 @@ type CurveParams struct { Cofactor fr.Element Order big.Int Base PointAffine - // edwardsAMinusD is the Edwards-model coefficient a-d used by the birational map. - edwardsAMinusD fr.Element - // weierstrassXShift is the x-translation A_M/3 from Montgomery to Weierstrass form. - weierstrassXShift fr.Element - // weierstrassA is the a-coefficient of the working short Weierstrass model. - weierstrassA fr.Element - // torsionPoint2 is the rational 2-torsion point used by the subgroup test. - torsionPoint2 weierstrassPointAffine - // torsionPoint4 is the rational 4-torsion generator used by the subgroup test. - torsionPoint4 weierstrassPointAffine - // tangentSlopeAtT4 is the tangent slope at torsionPoint4 on the working Weierstrass model. - tangentSlopeAtT4 fr.Element } // GetEdwardsCurve returns the twisted Edwards curve on bls12-377/Fr diff --git a/ecc/bls12-377/twistededwards/subgroup.go b/ecc/bls12-377/twistededwards/subgroup.go index 341c139578..75fca98a2c 100644 --- a/ecc/bls12-377/twistededwards/subgroup.go +++ b/ecc/bls12-377/twistededwards/subgroup.go @@ -11,19 +11,36 @@ type weierstrassPointAffine struct { X, Y fr.Element } +type subgroupParams struct { + // edwardsAMinusD is the Edwards-model coefficient a-d used by the birational map. + edwardsAMinusD fr.Element + // weierstrassXShift is the x-translation A_M/3 from Montgomery to Weierstrass form. + weierstrassXShift fr.Element + // weierstrassA is the a-coefficient of the working short Weierstrass model. + weierstrassA fr.Element + // torsionPoint2 is the rational 2-torsion point used by the subgroup test. + torsionPoint2 weierstrassPointAffine + // torsionPoint4 is the rational 4-torsion generator used by the subgroup test. + torsionPoint4 weierstrassPointAffine + // tangentSlopeAtT4 is the tangent slope at torsionPoint4 on the working Weierstrass model. + tangentSlopeAtT4 fr.Element +} + +var subgroupData subgroupParams + func initCofactorSubgroupParams() { var three, inv3 fr.Element three.SetUint64(3) inv3.Inverse(&three) var montA, montB fr.Element - curveParams.edwardsAMinusD.Sub(&curveParams.A, &curveParams.D) + subgroupData.edwardsAMinusD.Sub(&curveParams.A, &curveParams.D) montA.Add(&curveParams.A, &curveParams.D).Double(&montA) - montB.Square(&curveParams.edwardsAMinusD) + montB.Square(&subgroupData.edwardsAMinusD) - curveParams.weierstrassXShift.Mul(&montA, &inv3) - curveParams.weierstrassA.Square(&montA).Mul(&curveParams.weierstrassA, &inv3).Neg(&curveParams.weierstrassA) - curveParams.weierstrassA.Add(&curveParams.weierstrassA, &montB) + subgroupData.weierstrassXShift.Mul(&montA, &inv3) + subgroupData.weierstrassA.Square(&montA).Mul(&subgroupData.weierstrassA, &inv3).Neg(&subgroupData.weierstrassA) + subgroupData.weierstrassA.Add(&subgroupData.weierstrassA, &montB) var sqrtA fr.Element var t4 PointAffine @@ -33,9 +50,9 @@ func initCofactorSubgroupParams() { } t4.Y.SetZero() t4.X.Inverse(&sqrtA) - mapEdwardsToWeierstrass(&t4, &curveParams.torsionPoint4) - weierstrassTangentSlope(&curveParams.tangentSlopeAtT4, &curveParams.torsionPoint4) - weierstrassDouble(&curveParams.torsionPoint2, &curveParams.torsionPoint4) + mapEdwardsToWeierstrass(&t4, &subgroupData.torsionPoint4) + weierstrassTangentSlope(&subgroupData.tangentSlopeAtT4, &subgroupData.torsionPoint4) + weierstrassDouble(&subgroupData.torsionPoint2, &subgroupData.torsionPoint4) } func mapEdwardsToWeierstrass(p *PointAffine, out *weierstrassPointAffine) { @@ -49,12 +66,12 @@ func mapEdwardsToWeierstrass(p *PointAffine, out *weierstrassPointAffine) { Mul(&den, &p.X) denInv.Inverse(&den) - out.Y.Set(&curveParams.edwardsAMinusD). + out.Y.Set(&subgroupData.edwardsAMinusD). Mul(&out.Y, &num). Mul(&out.Y, &two). Mul(&out.Y, &denInv) u.Mul(&out.Y, &p.X).Mul(&u, &inv2) - out.X.Add(&u, &curveParams.weierstrassXShift) + out.X.Add(&u, &subgroupData.weierstrassXShift) } func weierstrassDouble(out, p *weierstrassPointAffine) { @@ -69,7 +86,7 @@ func weierstrassTangentSlope(lambda *fr.Element, p *weierstrassPointAffine) { var num, den fr.Element num.Square(&p.X) fr.MulBy3(&num) - num.Add(&num, &curveParams.weierstrassA) + num.Add(&num, &subgroupData.weierstrassA) den.Double(&p.Y).Inverse(&den) lambda.Mul(&num, &den) } @@ -321,8 +338,8 @@ func (p *PointAffine) IsInSubGroup() bool { return false } var l1, v1, z, check, tmp fr.Element - evaluateTangentLine(&l1, &r.X, &r.Y, &curveParams.torsionPoint4, &curveParams.tangentSlopeAtT4) - v1.Sub(&r.X, &curveParams.torsionPoint2.X) + evaluateTangentLine(&l1, &r.X, &r.Y, &subgroupData.torsionPoint4, &subgroupData.tangentSlopeAtT4) + v1.Sub(&r.X, &subgroupData.torsionPoint2.X) z.Square(&l1) tmp.Square(&v1).Mul(&tmp, &v1) z.Mul(&z, &tmp) diff --git a/ecc/bls12-381/twistededwards/curve.go b/ecc/bls12-381/twistededwards/curve.go index 149197d8ba..0adb551711 100644 --- a/ecc/bls12-381/twistededwards/curve.go +++ b/ecc/bls12-381/twistededwards/curve.go @@ -18,22 +18,6 @@ type CurveParams struct { Cofactor fr.Element Order big.Int Base PointAffine - // edwardsAMinusD is the Edwards-model coefficient a-d used by the birational map. - edwardsAMinusD fr.Element - // weierstrassXShift is the x-translation A_M/3 from Montgomery to Weierstrass form. - weierstrassXShift fr.Element - // weierstrassA is the a-coefficient of the working short Weierstrass model. - weierstrassA fr.Element - // torsionPoint2 is the rational 2-torsion point used by the subgroup test. - torsionPoint2 weierstrassPointAffine - // torsionPoint4 is the rational 4-torsion generator used by the subgroup test. - torsionPoint4 weierstrassPointAffine - // tangentSlopeAtT4 is the tangent slope at torsionPoint4 on the working Weierstrass model. - tangentSlopeAtT4 fr.Element - // torsionPoint8 is the rational 8-torsion generator used by the subgroup test. - torsionPoint8 weierstrassPointAffine - // tangentSlopeAtT8 is the tangent slope at torsionPoint8 on the working Weierstrass model. - tangentSlopeAtT8 fr.Element } // GetEdwardsCurve returns the twisted Edwards curve on bls12-381/Fr diff --git a/ecc/bls12-381/twistededwards/subgroup.go b/ecc/bls12-381/twistededwards/subgroup.go index b33f65b4ee..83b06105eb 100644 --- a/ecc/bls12-381/twistededwards/subgroup.go +++ b/ecc/bls12-381/twistededwards/subgroup.go @@ -11,19 +11,40 @@ type weierstrassPointAffine struct { X, Y fr.Element } +type subgroupParams struct { + // edwardsAMinusD is the Edwards-model coefficient a-d used by the birational map. + edwardsAMinusD fr.Element + // weierstrassXShift is the x-translation A_M/3 from Montgomery to Weierstrass form. + weierstrassXShift fr.Element + // weierstrassA is the a-coefficient of the working short Weierstrass model. + weierstrassA fr.Element + // torsionPoint2 is the rational 2-torsion point used by the subgroup test. + torsionPoint2 weierstrassPointAffine + // torsionPoint4 is the rational 4-torsion generator used by the subgroup test. + torsionPoint4 weierstrassPointAffine + // tangentSlopeAtT4 is the tangent slope at torsionPoint4 on the working Weierstrass model. + tangentSlopeAtT4 fr.Element + // torsionPoint8 is the rational 8-torsion generator used by the subgroup test. + torsionPoint8 weierstrassPointAffine + // tangentSlopeAtT8 is the tangent slope at torsionPoint8 on the working Weierstrass model. + tangentSlopeAtT8 fr.Element +} + +var subgroupData subgroupParams + func initCofactorSubgroupParams() { var three, inv3 fr.Element three.SetUint64(3) inv3.Inverse(&three) var montA, montB fr.Element - curveParams.edwardsAMinusD.Sub(&curveParams.A, &curveParams.D) + subgroupData.edwardsAMinusD.Sub(&curveParams.A, &curveParams.D) montA.Add(&curveParams.A, &curveParams.D).Double(&montA) - montB.Square(&curveParams.edwardsAMinusD) + montB.Square(&subgroupData.edwardsAMinusD) - curveParams.weierstrassXShift.Mul(&montA, &inv3) - curveParams.weierstrassA.Square(&montA).Mul(&curveParams.weierstrassA, &inv3).Neg(&curveParams.weierstrassA) - curveParams.weierstrassA.Add(&curveParams.weierstrassA, &montB) + subgroupData.weierstrassXShift.Mul(&montA, &inv3) + subgroupData.weierstrassA.Square(&montA).Mul(&subgroupData.weierstrassA, &inv3).Neg(&subgroupData.weierstrassA) + subgroupData.weierstrassA.Add(&subgroupData.weierstrassA, &montB) var sqrtA fr.Element var t4 PointAffine @@ -33,9 +54,9 @@ func initCofactorSubgroupParams() { } t4.Y.SetZero() t4.X.Inverse(&sqrtA) - mapEdwardsToWeierstrass(&t4, &curveParams.torsionPoint4) - weierstrassTangentSlope(&curveParams.tangentSlopeAtT4, &curveParams.torsionPoint4) - weierstrassDouble(&curveParams.torsionPoint2, &curveParams.torsionPoint4) + mapEdwardsToWeierstrass(&t4, &subgroupData.torsionPoint4) + weierstrassTangentSlope(&subgroupData.tangentSlopeAtT4, &subgroupData.torsionPoint4) + weierstrassDouble(&subgroupData.torsionPoint2, &subgroupData.torsionPoint4) initCofactorEightTorsion(&t4) } func initCofactorEightTorsion(t4 *PointAffine) { @@ -73,8 +94,8 @@ func initCofactorEightTorsion(t4 *PointAffine) { if !dbl.Equal(t4) { return false } - mapEdwardsToWeierstrass(&q, &curveParams.torsionPoint8) - weierstrassTangentSlope(&curveParams.tangentSlopeAtT8, &curveParams.torsionPoint8) + mapEdwardsToWeierstrass(&q, &subgroupData.torsionPoint8) + weierstrassTangentSlope(&subgroupData.tangentSlopeAtT8, &subgroupData.torsionPoint8) return true } @@ -103,12 +124,12 @@ func mapEdwardsToWeierstrass(p *PointAffine, out *weierstrassPointAffine) { Mul(&den, &p.X) denInv.Inverse(&den) - out.Y.Set(&curveParams.edwardsAMinusD). + out.Y.Set(&subgroupData.edwardsAMinusD). Mul(&out.Y, &num). Mul(&out.Y, &two). Mul(&out.Y, &denInv) u.Mul(&out.Y, &p.X).Mul(&u, &inv2) - out.X.Add(&u, &curveParams.weierstrassXShift) + out.X.Add(&u, &subgroupData.weierstrassXShift) } func weierstrassDouble(out, p *weierstrassPointAffine) { @@ -123,7 +144,7 @@ func weierstrassTangentSlope(lambda *fr.Element, p *weierstrassPointAffine) { var num, den fr.Element num.Square(&p.X) fr.MulBy3(&num) - num.Add(&num, &curveParams.weierstrassA) + num.Add(&num, &subgroupData.weierstrassA) den.Double(&p.Y).Inverse(&den) lambda.Mul(&num, &den) } @@ -408,10 +429,10 @@ func (p *PointAffine) IsInSubGroup() bool { return false } var l1, l2, v1, v2, z, check, tmp fr.Element - evaluateTangentLine(&l1, &r.X, &r.Y, &curveParams.torsionPoint8, &curveParams.tangentSlopeAtT8) - evaluateTangentLine(&l2, &r.X, &r.Y, &curveParams.torsionPoint4, &curveParams.tangentSlopeAtT4) - v1.Sub(&r.X, &curveParams.torsionPoint4.X) - v2.Sub(&r.X, &curveParams.torsionPoint2.X) + evaluateTangentLine(&l1, &r.X, &r.Y, &subgroupData.torsionPoint8, &subgroupData.tangentSlopeAtT8) + evaluateTangentLine(&l2, &r.X, &r.Y, &subgroupData.torsionPoint4, &subgroupData.tangentSlopeAtT4) + v1.Sub(&r.X, &subgroupData.torsionPoint4.X) + v2.Sub(&r.X, &subgroupData.torsionPoint2.X) z.Square(&l1).Square(&z) tmp.Square(&v1).Square(&tmp) z.Mul(&z, &tmp) diff --git a/ecc/bls24-315/twistededwards/curve.go b/ecc/bls24-315/twistededwards/curve.go index 55b87c8821..75842416b4 100644 --- a/ecc/bls24-315/twistededwards/curve.go +++ b/ecc/bls24-315/twistededwards/curve.go @@ -18,22 +18,6 @@ type CurveParams struct { Cofactor fr.Element Order big.Int Base PointAffine - // edwardsAMinusD is the Edwards-model coefficient a-d used by the birational map. - edwardsAMinusD fr.Element - // weierstrassXShift is the x-translation A_M/3 from Montgomery to Weierstrass form. - weierstrassXShift fr.Element - // weierstrassA is the a-coefficient of the working short Weierstrass model. - weierstrassA fr.Element - // torsionPoint2 is the rational 2-torsion point used by the subgroup test. - torsionPoint2 weierstrassPointAffine - // torsionPoint4 is the rational 4-torsion generator used by the subgroup test. - torsionPoint4 weierstrassPointAffine - // tangentSlopeAtT4 is the tangent slope at torsionPoint4 on the working Weierstrass model. - tangentSlopeAtT4 fr.Element - // torsionPoint8 is the rational 8-torsion generator used by the subgroup test. - torsionPoint8 weierstrassPointAffine - // tangentSlopeAtT8 is the tangent slope at torsionPoint8 on the working Weierstrass model. - tangentSlopeAtT8 fr.Element } // GetEdwardsCurve returns the twisted Edwards curve on bls24-315/Fr diff --git a/ecc/bls24-315/twistededwards/subgroup.go b/ecc/bls24-315/twistededwards/subgroup.go index 9925a3869e..1ccf137283 100644 --- a/ecc/bls24-315/twistededwards/subgroup.go +++ b/ecc/bls24-315/twistededwards/subgroup.go @@ -11,19 +11,40 @@ type weierstrassPointAffine struct { X, Y fr.Element } +type subgroupParams struct { + // edwardsAMinusD is the Edwards-model coefficient a-d used by the birational map. + edwardsAMinusD fr.Element + // weierstrassXShift is the x-translation A_M/3 from Montgomery to Weierstrass form. + weierstrassXShift fr.Element + // weierstrassA is the a-coefficient of the working short Weierstrass model. + weierstrassA fr.Element + // torsionPoint2 is the rational 2-torsion point used by the subgroup test. + torsionPoint2 weierstrassPointAffine + // torsionPoint4 is the rational 4-torsion generator used by the subgroup test. + torsionPoint4 weierstrassPointAffine + // tangentSlopeAtT4 is the tangent slope at torsionPoint4 on the working Weierstrass model. + tangentSlopeAtT4 fr.Element + // torsionPoint8 is the rational 8-torsion generator used by the subgroup test. + torsionPoint8 weierstrassPointAffine + // tangentSlopeAtT8 is the tangent slope at torsionPoint8 on the working Weierstrass model. + tangentSlopeAtT8 fr.Element +} + +var subgroupData subgroupParams + func initCofactorSubgroupParams() { var three, inv3 fr.Element three.SetUint64(3) inv3.Inverse(&three) var montA, montB fr.Element - curveParams.edwardsAMinusD.Sub(&curveParams.A, &curveParams.D) + subgroupData.edwardsAMinusD.Sub(&curveParams.A, &curveParams.D) montA.Add(&curveParams.A, &curveParams.D).Double(&montA) - montB.Square(&curveParams.edwardsAMinusD) + montB.Square(&subgroupData.edwardsAMinusD) - curveParams.weierstrassXShift.Mul(&montA, &inv3) - curveParams.weierstrassA.Square(&montA).Mul(&curveParams.weierstrassA, &inv3).Neg(&curveParams.weierstrassA) - curveParams.weierstrassA.Add(&curveParams.weierstrassA, &montB) + subgroupData.weierstrassXShift.Mul(&montA, &inv3) + subgroupData.weierstrassA.Square(&montA).Mul(&subgroupData.weierstrassA, &inv3).Neg(&subgroupData.weierstrassA) + subgroupData.weierstrassA.Add(&subgroupData.weierstrassA, &montB) var sqrtA fr.Element var t4 PointAffine @@ -33,9 +54,9 @@ func initCofactorSubgroupParams() { } t4.Y.SetZero() t4.X.Inverse(&sqrtA) - mapEdwardsToWeierstrass(&t4, &curveParams.torsionPoint4) - weierstrassTangentSlope(&curveParams.tangentSlopeAtT4, &curveParams.torsionPoint4) - weierstrassDouble(&curveParams.torsionPoint2, &curveParams.torsionPoint4) + mapEdwardsToWeierstrass(&t4, &subgroupData.torsionPoint4) + weierstrassTangentSlope(&subgroupData.tangentSlopeAtT4, &subgroupData.torsionPoint4) + weierstrassDouble(&subgroupData.torsionPoint2, &subgroupData.torsionPoint4) initCofactorEightTorsion(&t4) } func initCofactorEightTorsion(t4 *PointAffine) { @@ -73,8 +94,8 @@ func initCofactorEightTorsion(t4 *PointAffine) { if !dbl.Equal(t4) { return false } - mapEdwardsToWeierstrass(&q, &curveParams.torsionPoint8) - weierstrassTangentSlope(&curveParams.tangentSlopeAtT8, &curveParams.torsionPoint8) + mapEdwardsToWeierstrass(&q, &subgroupData.torsionPoint8) + weierstrassTangentSlope(&subgroupData.tangentSlopeAtT8, &subgroupData.torsionPoint8) return true } @@ -103,12 +124,12 @@ func mapEdwardsToWeierstrass(p *PointAffine, out *weierstrassPointAffine) { Mul(&den, &p.X) denInv.Inverse(&den) - out.Y.Set(&curveParams.edwardsAMinusD). + out.Y.Set(&subgroupData.edwardsAMinusD). Mul(&out.Y, &num). Mul(&out.Y, &two). Mul(&out.Y, &denInv) u.Mul(&out.Y, &p.X).Mul(&u, &inv2) - out.X.Add(&u, &curveParams.weierstrassXShift) + out.X.Add(&u, &subgroupData.weierstrassXShift) } func weierstrassDouble(out, p *weierstrassPointAffine) { @@ -123,7 +144,7 @@ func weierstrassTangentSlope(lambda *fr.Element, p *weierstrassPointAffine) { var num, den fr.Element num.Square(&p.X) fr.MulBy3(&num) - num.Add(&num, &curveParams.weierstrassA) + num.Add(&num, &subgroupData.weierstrassA) den.Double(&p.Y).Inverse(&den) lambda.Mul(&num, &den) } @@ -447,10 +468,10 @@ func (p *PointAffine) IsInSubGroup() bool { return false } var l1, l2, v1, v2, z, check, tmp fr.Element - evaluateTangentLine(&l1, &r.X, &r.Y, &curveParams.torsionPoint8, &curveParams.tangentSlopeAtT8) - evaluateTangentLine(&l2, &r.X, &r.Y, &curveParams.torsionPoint4, &curveParams.tangentSlopeAtT4) - v1.Sub(&r.X, &curveParams.torsionPoint4.X) - v2.Sub(&r.X, &curveParams.torsionPoint2.X) + evaluateTangentLine(&l1, &r.X, &r.Y, &subgroupData.torsionPoint8, &subgroupData.tangentSlopeAtT8) + evaluateTangentLine(&l2, &r.X, &r.Y, &subgroupData.torsionPoint4, &subgroupData.tangentSlopeAtT4) + v1.Sub(&r.X, &subgroupData.torsionPoint4.X) + v2.Sub(&r.X, &subgroupData.torsionPoint2.X) z.Square(&l1).Square(&z) tmp.Square(&v1).Square(&tmp) z.Mul(&z, &tmp) diff --git a/ecc/bls24-317/twistededwards/curve.go b/ecc/bls24-317/twistededwards/curve.go index 40af56099e..df7e9326c4 100644 --- a/ecc/bls24-317/twistededwards/curve.go +++ b/ecc/bls24-317/twistededwards/curve.go @@ -18,22 +18,6 @@ type CurveParams struct { Cofactor fr.Element Order big.Int Base PointAffine - // edwardsAMinusD is the Edwards-model coefficient a-d used by the birational map. - edwardsAMinusD fr.Element - // weierstrassXShift is the x-translation A_M/3 from Montgomery to Weierstrass form. - weierstrassXShift fr.Element - // weierstrassA is the a-coefficient of the working short Weierstrass model. - weierstrassA fr.Element - // torsionPoint2 is the rational 2-torsion point used by the subgroup test. - torsionPoint2 weierstrassPointAffine - // torsionPoint4 is the rational 4-torsion generator used by the subgroup test. - torsionPoint4 weierstrassPointAffine - // tangentSlopeAtT4 is the tangent slope at torsionPoint4 on the working Weierstrass model. - tangentSlopeAtT4 fr.Element - // torsionPoint8 is the rational 8-torsion generator used by the subgroup test. - torsionPoint8 weierstrassPointAffine - // tangentSlopeAtT8 is the tangent slope at torsionPoint8 on the working Weierstrass model. - tangentSlopeAtT8 fr.Element } // GetEdwardsCurve returns the twisted Edwards curve on bls24-317/Fr diff --git a/ecc/bls24-317/twistededwards/subgroup.go b/ecc/bls24-317/twistededwards/subgroup.go index d5a0a84cd3..91e0ea492f 100644 --- a/ecc/bls24-317/twistededwards/subgroup.go +++ b/ecc/bls24-317/twistededwards/subgroup.go @@ -11,19 +11,40 @@ type weierstrassPointAffine struct { X, Y fr.Element } +type subgroupParams struct { + // edwardsAMinusD is the Edwards-model coefficient a-d used by the birational map. + edwardsAMinusD fr.Element + // weierstrassXShift is the x-translation A_M/3 from Montgomery to Weierstrass form. + weierstrassXShift fr.Element + // weierstrassA is the a-coefficient of the working short Weierstrass model. + weierstrassA fr.Element + // torsionPoint2 is the rational 2-torsion point used by the subgroup test. + torsionPoint2 weierstrassPointAffine + // torsionPoint4 is the rational 4-torsion generator used by the subgroup test. + torsionPoint4 weierstrassPointAffine + // tangentSlopeAtT4 is the tangent slope at torsionPoint4 on the working Weierstrass model. + tangentSlopeAtT4 fr.Element + // torsionPoint8 is the rational 8-torsion generator used by the subgroup test. + torsionPoint8 weierstrassPointAffine + // tangentSlopeAtT8 is the tangent slope at torsionPoint8 on the working Weierstrass model. + tangentSlopeAtT8 fr.Element +} + +var subgroupData subgroupParams + func initCofactorSubgroupParams() { var three, inv3 fr.Element three.SetUint64(3) inv3.Inverse(&three) var montA, montB fr.Element - curveParams.edwardsAMinusD.Sub(&curveParams.A, &curveParams.D) + subgroupData.edwardsAMinusD.Sub(&curveParams.A, &curveParams.D) montA.Add(&curveParams.A, &curveParams.D).Double(&montA) - montB.Square(&curveParams.edwardsAMinusD) + montB.Square(&subgroupData.edwardsAMinusD) - curveParams.weierstrassXShift.Mul(&montA, &inv3) - curveParams.weierstrassA.Square(&montA).Mul(&curveParams.weierstrassA, &inv3).Neg(&curveParams.weierstrassA) - curveParams.weierstrassA.Add(&curveParams.weierstrassA, &montB) + subgroupData.weierstrassXShift.Mul(&montA, &inv3) + subgroupData.weierstrassA.Square(&montA).Mul(&subgroupData.weierstrassA, &inv3).Neg(&subgroupData.weierstrassA) + subgroupData.weierstrassA.Add(&subgroupData.weierstrassA, &montB) var sqrtA fr.Element var t4 PointAffine @@ -33,9 +54,9 @@ func initCofactorSubgroupParams() { } t4.Y.SetZero() t4.X.Inverse(&sqrtA) - mapEdwardsToWeierstrass(&t4, &curveParams.torsionPoint4) - weierstrassTangentSlope(&curveParams.tangentSlopeAtT4, &curveParams.torsionPoint4) - weierstrassDouble(&curveParams.torsionPoint2, &curveParams.torsionPoint4) + mapEdwardsToWeierstrass(&t4, &subgroupData.torsionPoint4) + weierstrassTangentSlope(&subgroupData.tangentSlopeAtT4, &subgroupData.torsionPoint4) + weierstrassDouble(&subgroupData.torsionPoint2, &subgroupData.torsionPoint4) initCofactorEightTorsion(&t4) } func initCofactorEightTorsion(t4 *PointAffine) { @@ -73,8 +94,8 @@ func initCofactorEightTorsion(t4 *PointAffine) { if !dbl.Equal(t4) { return false } - mapEdwardsToWeierstrass(&q, &curveParams.torsionPoint8) - weierstrassTangentSlope(&curveParams.tangentSlopeAtT8, &curveParams.torsionPoint8) + mapEdwardsToWeierstrass(&q, &subgroupData.torsionPoint8) + weierstrassTangentSlope(&subgroupData.tangentSlopeAtT8, &subgroupData.torsionPoint8) return true } @@ -103,12 +124,12 @@ func mapEdwardsToWeierstrass(p *PointAffine, out *weierstrassPointAffine) { Mul(&den, &p.X) denInv.Inverse(&den) - out.Y.Set(&curveParams.edwardsAMinusD). + out.Y.Set(&subgroupData.edwardsAMinusD). Mul(&out.Y, &num). Mul(&out.Y, &two). Mul(&out.Y, &denInv) u.Mul(&out.Y, &p.X).Mul(&u, &inv2) - out.X.Add(&u, &curveParams.weierstrassXShift) + out.X.Add(&u, &subgroupData.weierstrassXShift) } func weierstrassDouble(out, p *weierstrassPointAffine) { @@ -123,7 +144,7 @@ func weierstrassTangentSlope(lambda *fr.Element, p *weierstrassPointAffine) { var num, den fr.Element num.Square(&p.X) fr.MulBy3(&num) - num.Add(&num, &curveParams.weierstrassA) + num.Add(&num, &subgroupData.weierstrassA) den.Double(&p.Y).Inverse(&den) lambda.Mul(&num, &den) } @@ -409,10 +430,10 @@ func (p *PointAffine) IsInSubGroup() bool { return false } var l1, l2, v1, v2, z, check, tmp fr.Element - evaluateTangentLine(&l1, &r.X, &r.Y, &curveParams.torsionPoint8, &curveParams.tangentSlopeAtT8) - evaluateTangentLine(&l2, &r.X, &r.Y, &curveParams.torsionPoint4, &curveParams.tangentSlopeAtT4) - v1.Sub(&r.X, &curveParams.torsionPoint4.X) - v2.Sub(&r.X, &curveParams.torsionPoint2.X) + evaluateTangentLine(&l1, &r.X, &r.Y, &subgroupData.torsionPoint8, &subgroupData.tangentSlopeAtT8) + evaluateTangentLine(&l2, &r.X, &r.Y, &subgroupData.torsionPoint4, &subgroupData.tangentSlopeAtT4) + v1.Sub(&r.X, &subgroupData.torsionPoint4.X) + v2.Sub(&r.X, &subgroupData.torsionPoint2.X) z.Square(&l1).Square(&z) tmp.Square(&v1).Square(&tmp) z.Mul(&z, &tmp) diff --git a/ecc/bn254/twistededwards/curve.go b/ecc/bn254/twistededwards/curve.go index 757a18cfab..d50a12fd15 100644 --- a/ecc/bn254/twistededwards/curve.go +++ b/ecc/bn254/twistededwards/curve.go @@ -18,22 +18,6 @@ type CurveParams struct { Cofactor fr.Element Order big.Int Base PointAffine - // edwardsAMinusD is the Edwards-model coefficient a-d used by the birational map. - edwardsAMinusD fr.Element - // weierstrassXShift is the x-translation A_M/3 from Montgomery to Weierstrass form. - weierstrassXShift fr.Element - // weierstrassA is the a-coefficient of the working short Weierstrass model. - weierstrassA fr.Element - // torsionPoint2 is the rational 2-torsion point used by the subgroup test. - torsionPoint2 weierstrassPointAffine - // torsionPoint4 is the rational 4-torsion generator used by the subgroup test. - torsionPoint4 weierstrassPointAffine - // tangentSlopeAtT4 is the tangent slope at torsionPoint4 on the working Weierstrass model. - tangentSlopeAtT4 fr.Element - // torsionPoint8 is the rational 8-torsion generator used by the subgroup test. - torsionPoint8 weierstrassPointAffine - // tangentSlopeAtT8 is the tangent slope at torsionPoint8 on the working Weierstrass model. - tangentSlopeAtT8 fr.Element } // GetEdwardsCurve returns the twisted Edwards curve on bn254/Fr diff --git a/ecc/bn254/twistededwards/subgroup.go b/ecc/bn254/twistededwards/subgroup.go index a818017f56..f85503ad64 100644 --- a/ecc/bn254/twistededwards/subgroup.go +++ b/ecc/bn254/twistededwards/subgroup.go @@ -11,19 +11,40 @@ type weierstrassPointAffine struct { X, Y fr.Element } +type subgroupParams struct { + // edwardsAMinusD is the Edwards-model coefficient a-d used by the birational map. + edwardsAMinusD fr.Element + // weierstrassXShift is the x-translation A_M/3 from Montgomery to Weierstrass form. + weierstrassXShift fr.Element + // weierstrassA is the a-coefficient of the working short Weierstrass model. + weierstrassA fr.Element + // torsionPoint2 is the rational 2-torsion point used by the subgroup test. + torsionPoint2 weierstrassPointAffine + // torsionPoint4 is the rational 4-torsion generator used by the subgroup test. + torsionPoint4 weierstrassPointAffine + // tangentSlopeAtT4 is the tangent slope at torsionPoint4 on the working Weierstrass model. + tangentSlopeAtT4 fr.Element + // torsionPoint8 is the rational 8-torsion generator used by the subgroup test. + torsionPoint8 weierstrassPointAffine + // tangentSlopeAtT8 is the tangent slope at torsionPoint8 on the working Weierstrass model. + tangentSlopeAtT8 fr.Element +} + +var subgroupData subgroupParams + func initCofactorSubgroupParams() { var three, inv3 fr.Element three.SetUint64(3) inv3.Inverse(&three) var montA, montB fr.Element - curveParams.edwardsAMinusD.Sub(&curveParams.A, &curveParams.D) + subgroupData.edwardsAMinusD.Sub(&curveParams.A, &curveParams.D) montA.Add(&curveParams.A, &curveParams.D).Double(&montA) - montB.Square(&curveParams.edwardsAMinusD) + montB.Square(&subgroupData.edwardsAMinusD) - curveParams.weierstrassXShift.Mul(&montA, &inv3) - curveParams.weierstrassA.Square(&montA).Mul(&curveParams.weierstrassA, &inv3).Neg(&curveParams.weierstrassA) - curveParams.weierstrassA.Add(&curveParams.weierstrassA, &montB) + subgroupData.weierstrassXShift.Mul(&montA, &inv3) + subgroupData.weierstrassA.Square(&montA).Mul(&subgroupData.weierstrassA, &inv3).Neg(&subgroupData.weierstrassA) + subgroupData.weierstrassA.Add(&subgroupData.weierstrassA, &montB) var sqrtA fr.Element var t4 PointAffine @@ -33,9 +54,9 @@ func initCofactorSubgroupParams() { } t4.Y.SetZero() t4.X.Inverse(&sqrtA) - mapEdwardsToWeierstrass(&t4, &curveParams.torsionPoint4) - weierstrassTangentSlope(&curveParams.tangentSlopeAtT4, &curveParams.torsionPoint4) - weierstrassDouble(&curveParams.torsionPoint2, &curveParams.torsionPoint4) + mapEdwardsToWeierstrass(&t4, &subgroupData.torsionPoint4) + weierstrassTangentSlope(&subgroupData.tangentSlopeAtT4, &subgroupData.torsionPoint4) + weierstrassDouble(&subgroupData.torsionPoint2, &subgroupData.torsionPoint4) initCofactorEightTorsion(&t4) } func initCofactorEightTorsion(t4 *PointAffine) { @@ -73,8 +94,8 @@ func initCofactorEightTorsion(t4 *PointAffine) { if !dbl.Equal(t4) { return false } - mapEdwardsToWeierstrass(&q, &curveParams.torsionPoint8) - weierstrassTangentSlope(&curveParams.tangentSlopeAtT8, &curveParams.torsionPoint8) + mapEdwardsToWeierstrass(&q, &subgroupData.torsionPoint8) + weierstrassTangentSlope(&subgroupData.tangentSlopeAtT8, &subgroupData.torsionPoint8) return true } @@ -103,12 +124,12 @@ func mapEdwardsToWeierstrass(p *PointAffine, out *weierstrassPointAffine) { Mul(&den, &p.X) denInv.Inverse(&den) - out.Y.Set(&curveParams.edwardsAMinusD). + out.Y.Set(&subgroupData.edwardsAMinusD). Mul(&out.Y, &num). Mul(&out.Y, &two). Mul(&out.Y, &denInv) u.Mul(&out.Y, &p.X).Mul(&u, &inv2) - out.X.Add(&u, &curveParams.weierstrassXShift) + out.X.Add(&u, &subgroupData.weierstrassXShift) } func weierstrassDouble(out, p *weierstrassPointAffine) { @@ -123,7 +144,7 @@ func weierstrassTangentSlope(lambda *fr.Element, p *weierstrassPointAffine) { var num, den fr.Element num.Square(&p.X) fr.MulBy3(&num) - num.Add(&num, &curveParams.weierstrassA) + num.Add(&num, &subgroupData.weierstrassA) den.Double(&p.Y).Inverse(&den) lambda.Mul(&num, &den) } @@ -458,10 +479,10 @@ func (p *PointAffine) IsInSubGroup() bool { return false } var l1, l2, v1, v2, z, check, tmp fr.Element - evaluateTangentLine(&l1, &r.X, &r.Y, &curveParams.torsionPoint8, &curveParams.tangentSlopeAtT8) - evaluateTangentLine(&l2, &r.X, &r.Y, &curveParams.torsionPoint4, &curveParams.tangentSlopeAtT4) - v1.Sub(&r.X, &curveParams.torsionPoint4.X) - v2.Sub(&r.X, &curveParams.torsionPoint2.X) + evaluateTangentLine(&l1, &r.X, &r.Y, &subgroupData.torsionPoint8, &subgroupData.tangentSlopeAtT8) + evaluateTangentLine(&l2, &r.X, &r.Y, &subgroupData.torsionPoint4, &subgroupData.tangentSlopeAtT4) + v1.Sub(&r.X, &subgroupData.torsionPoint4.X) + v2.Sub(&r.X, &subgroupData.torsionPoint2.X) z.Square(&l1).Square(&z) tmp.Square(&v1).Square(&tmp) z.Mul(&z, &tmp) diff --git a/ecc/bw6-633/twistededwards/curve.go b/ecc/bw6-633/twistededwards/curve.go index 11d4ad41fa..aaa2c97cf4 100644 --- a/ecc/bw6-633/twistededwards/curve.go +++ b/ecc/bw6-633/twistededwards/curve.go @@ -18,22 +18,6 @@ type CurveParams struct { Cofactor fr.Element Order big.Int Base PointAffine - // edwardsAMinusD is the Edwards-model coefficient a-d used by the birational map. - edwardsAMinusD fr.Element - // weierstrassXShift is the x-translation A_M/3 from Montgomery to Weierstrass form. - weierstrassXShift fr.Element - // weierstrassA is the a-coefficient of the working short Weierstrass model. - weierstrassA fr.Element - // torsionPoint2 is the rational 2-torsion point used by the subgroup test. - torsionPoint2 weierstrassPointAffine - // torsionPoint4 is the rational 4-torsion generator used by the subgroup test. - torsionPoint4 weierstrassPointAffine - // tangentSlopeAtT4 is the tangent slope at torsionPoint4 on the working Weierstrass model. - tangentSlopeAtT4 fr.Element - // torsionPoint8 is the rational 8-torsion generator used by the subgroup test. - torsionPoint8 weierstrassPointAffine - // tangentSlopeAtT8 is the tangent slope at torsionPoint8 on the working Weierstrass model. - tangentSlopeAtT8 fr.Element } // GetEdwardsCurve returns the twisted Edwards curve on bw6-633/Fr diff --git a/ecc/bw6-633/twistededwards/subgroup.go b/ecc/bw6-633/twistededwards/subgroup.go index ec28422ad5..5b592457b3 100644 --- a/ecc/bw6-633/twistededwards/subgroup.go +++ b/ecc/bw6-633/twistededwards/subgroup.go @@ -11,19 +11,40 @@ type weierstrassPointAffine struct { X, Y fr.Element } +type subgroupParams struct { + // edwardsAMinusD is the Edwards-model coefficient a-d used by the birational map. + edwardsAMinusD fr.Element + // weierstrassXShift is the x-translation A_M/3 from Montgomery to Weierstrass form. + weierstrassXShift fr.Element + // weierstrassA is the a-coefficient of the working short Weierstrass model. + weierstrassA fr.Element + // torsionPoint2 is the rational 2-torsion point used by the subgroup test. + torsionPoint2 weierstrassPointAffine + // torsionPoint4 is the rational 4-torsion generator used by the subgroup test. + torsionPoint4 weierstrassPointAffine + // tangentSlopeAtT4 is the tangent slope at torsionPoint4 on the working Weierstrass model. + tangentSlopeAtT4 fr.Element + // torsionPoint8 is the rational 8-torsion generator used by the subgroup test. + torsionPoint8 weierstrassPointAffine + // tangentSlopeAtT8 is the tangent slope at torsionPoint8 on the working Weierstrass model. + tangentSlopeAtT8 fr.Element +} + +var subgroupData subgroupParams + func initCofactorSubgroupParams() { var three, inv3 fr.Element three.SetUint64(3) inv3.Inverse(&three) var montA, montB fr.Element - curveParams.edwardsAMinusD.Sub(&curveParams.A, &curveParams.D) + subgroupData.edwardsAMinusD.Sub(&curveParams.A, &curveParams.D) montA.Add(&curveParams.A, &curveParams.D).Double(&montA) - montB.Square(&curveParams.edwardsAMinusD) + montB.Square(&subgroupData.edwardsAMinusD) - curveParams.weierstrassXShift.Mul(&montA, &inv3) - curveParams.weierstrassA.Square(&montA).Mul(&curveParams.weierstrassA, &inv3).Neg(&curveParams.weierstrassA) - curveParams.weierstrassA.Add(&curveParams.weierstrassA, &montB) + subgroupData.weierstrassXShift.Mul(&montA, &inv3) + subgroupData.weierstrassA.Square(&montA).Mul(&subgroupData.weierstrassA, &inv3).Neg(&subgroupData.weierstrassA) + subgroupData.weierstrassA.Add(&subgroupData.weierstrassA, &montB) var sqrtA fr.Element var t4 PointAffine @@ -33,9 +54,9 @@ func initCofactorSubgroupParams() { } t4.Y.SetZero() t4.X.Inverse(&sqrtA) - mapEdwardsToWeierstrass(&t4, &curveParams.torsionPoint4) - weierstrassTangentSlope(&curveParams.tangentSlopeAtT4, &curveParams.torsionPoint4) - weierstrassDouble(&curveParams.torsionPoint2, &curveParams.torsionPoint4) + mapEdwardsToWeierstrass(&t4, &subgroupData.torsionPoint4) + weierstrassTangentSlope(&subgroupData.tangentSlopeAtT4, &subgroupData.torsionPoint4) + weierstrassDouble(&subgroupData.torsionPoint2, &subgroupData.torsionPoint4) initCofactorEightTorsion(&t4) } func initCofactorEightTorsion(t4 *PointAffine) { @@ -73,8 +94,8 @@ func initCofactorEightTorsion(t4 *PointAffine) { if !dbl.Equal(t4) { return false } - mapEdwardsToWeierstrass(&q, &curveParams.torsionPoint8) - weierstrassTangentSlope(&curveParams.tangentSlopeAtT8, &curveParams.torsionPoint8) + mapEdwardsToWeierstrass(&q, &subgroupData.torsionPoint8) + weierstrassTangentSlope(&subgroupData.tangentSlopeAtT8, &subgroupData.torsionPoint8) return true } @@ -103,12 +124,12 @@ func mapEdwardsToWeierstrass(p *PointAffine, out *weierstrassPointAffine) { Mul(&den, &p.X) denInv.Inverse(&den) - out.Y.Set(&curveParams.edwardsAMinusD). + out.Y.Set(&subgroupData.edwardsAMinusD). Mul(&out.Y, &num). Mul(&out.Y, &two). Mul(&out.Y, &denInv) u.Mul(&out.Y, &p.X).Mul(&u, &inv2) - out.X.Add(&u, &curveParams.weierstrassXShift) + out.X.Add(&u, &subgroupData.weierstrassXShift) } func weierstrassDouble(out, p *weierstrassPointAffine) { @@ -123,7 +144,7 @@ func weierstrassTangentSlope(lambda *fr.Element, p *weierstrassPointAffine) { var num, den fr.Element num.Square(&p.X) fr.MulBy3(&num) - num.Add(&num, &curveParams.weierstrassA) + num.Add(&num, &subgroupData.weierstrassA) den.Double(&p.Y).Inverse(&den) lambda.Mul(&num, &den) } @@ -506,10 +527,10 @@ func (p *PointAffine) IsInSubGroup() bool { return false } var l1, l2, v1, v2, z, check, tmp fr.Element - evaluateTangentLine(&l1, &r.X, &r.Y, &curveParams.torsionPoint8, &curveParams.tangentSlopeAtT8) - evaluateTangentLine(&l2, &r.X, &r.Y, &curveParams.torsionPoint4, &curveParams.tangentSlopeAtT4) - v1.Sub(&r.X, &curveParams.torsionPoint4.X) - v2.Sub(&r.X, &curveParams.torsionPoint2.X) + evaluateTangentLine(&l1, &r.X, &r.Y, &subgroupData.torsionPoint8, &subgroupData.tangentSlopeAtT8) + evaluateTangentLine(&l2, &r.X, &r.Y, &subgroupData.torsionPoint4, &subgroupData.tangentSlopeAtT4) + v1.Sub(&r.X, &subgroupData.torsionPoint4.X) + v2.Sub(&r.X, &subgroupData.torsionPoint2.X) z.Square(&l1).Square(&z) tmp.Square(&v1).Square(&tmp) z.Mul(&z, &tmp) diff --git a/ecc/bw6-761/twistededwards/curve.go b/ecc/bw6-761/twistededwards/curve.go index 11728c5b93..8d4aa44a8d 100644 --- a/ecc/bw6-761/twistededwards/curve.go +++ b/ecc/bw6-761/twistededwards/curve.go @@ -18,22 +18,6 @@ type CurveParams struct { Cofactor fr.Element Order big.Int Base PointAffine - // edwardsAMinusD is the Edwards-model coefficient a-d used by the birational map. - edwardsAMinusD fr.Element - // weierstrassXShift is the x-translation A_M/3 from Montgomery to Weierstrass form. - weierstrassXShift fr.Element - // weierstrassA is the a-coefficient of the working short Weierstrass model. - weierstrassA fr.Element - // torsionPoint2 is the rational 2-torsion point used by the subgroup test. - torsionPoint2 weierstrassPointAffine - // torsionPoint4 is the rational 4-torsion generator used by the subgroup test. - torsionPoint4 weierstrassPointAffine - // tangentSlopeAtT4 is the tangent slope at torsionPoint4 on the working Weierstrass model. - tangentSlopeAtT4 fr.Element - // torsionPoint8 is the rational 8-torsion generator used by the subgroup test. - torsionPoint8 weierstrassPointAffine - // tangentSlopeAtT8 is the tangent slope at torsionPoint8 on the working Weierstrass model. - tangentSlopeAtT8 fr.Element } // GetEdwardsCurve returns the twisted Edwards curve on bw6-761/Fr diff --git a/ecc/bw6-761/twistededwards/subgroup.go b/ecc/bw6-761/twistededwards/subgroup.go index 6fcfaf5421..ebccc081c5 100644 --- a/ecc/bw6-761/twistededwards/subgroup.go +++ b/ecc/bw6-761/twistededwards/subgroup.go @@ -11,19 +11,40 @@ type weierstrassPointAffine struct { X, Y fr.Element } +type subgroupParams struct { + // edwardsAMinusD is the Edwards-model coefficient a-d used by the birational map. + edwardsAMinusD fr.Element + // weierstrassXShift is the x-translation A_M/3 from Montgomery to Weierstrass form. + weierstrassXShift fr.Element + // weierstrassA is the a-coefficient of the working short Weierstrass model. + weierstrassA fr.Element + // torsionPoint2 is the rational 2-torsion point used by the subgroup test. + torsionPoint2 weierstrassPointAffine + // torsionPoint4 is the rational 4-torsion generator used by the subgroup test. + torsionPoint4 weierstrassPointAffine + // tangentSlopeAtT4 is the tangent slope at torsionPoint4 on the working Weierstrass model. + tangentSlopeAtT4 fr.Element + // torsionPoint8 is the rational 8-torsion generator used by the subgroup test. + torsionPoint8 weierstrassPointAffine + // tangentSlopeAtT8 is the tangent slope at torsionPoint8 on the working Weierstrass model. + tangentSlopeAtT8 fr.Element +} + +var subgroupData subgroupParams + func initCofactorSubgroupParams() { var three, inv3 fr.Element three.SetUint64(3) inv3.Inverse(&three) var montA, montB fr.Element - curveParams.edwardsAMinusD.Sub(&curveParams.A, &curveParams.D) + subgroupData.edwardsAMinusD.Sub(&curveParams.A, &curveParams.D) montA.Add(&curveParams.A, &curveParams.D).Double(&montA) - montB.Square(&curveParams.edwardsAMinusD) + montB.Square(&subgroupData.edwardsAMinusD) - curveParams.weierstrassXShift.Mul(&montA, &inv3) - curveParams.weierstrassA.Square(&montA).Mul(&curveParams.weierstrassA, &inv3).Neg(&curveParams.weierstrassA) - curveParams.weierstrassA.Add(&curveParams.weierstrassA, &montB) + subgroupData.weierstrassXShift.Mul(&montA, &inv3) + subgroupData.weierstrassA.Square(&montA).Mul(&subgroupData.weierstrassA, &inv3).Neg(&subgroupData.weierstrassA) + subgroupData.weierstrassA.Add(&subgroupData.weierstrassA, &montB) var sqrtA fr.Element var t4 PointAffine @@ -33,9 +54,9 @@ func initCofactorSubgroupParams() { } t4.Y.SetZero() t4.X.Inverse(&sqrtA) - mapEdwardsToWeierstrass(&t4, &curveParams.torsionPoint4) - weierstrassTangentSlope(&curveParams.tangentSlopeAtT4, &curveParams.torsionPoint4) - weierstrassDouble(&curveParams.torsionPoint2, &curveParams.torsionPoint4) + mapEdwardsToWeierstrass(&t4, &subgroupData.torsionPoint4) + weierstrassTangentSlope(&subgroupData.tangentSlopeAtT4, &subgroupData.torsionPoint4) + weierstrassDouble(&subgroupData.torsionPoint2, &subgroupData.torsionPoint4) initCofactorEightTorsion(&t4) } func initCofactorEightTorsion(t4 *PointAffine) { @@ -73,8 +94,8 @@ func initCofactorEightTorsion(t4 *PointAffine) { if !dbl.Equal(t4) { return false } - mapEdwardsToWeierstrass(&q, &curveParams.torsionPoint8) - weierstrassTangentSlope(&curveParams.tangentSlopeAtT8, &curveParams.torsionPoint8) + mapEdwardsToWeierstrass(&q, &subgroupData.torsionPoint8) + weierstrassTangentSlope(&subgroupData.tangentSlopeAtT8, &subgroupData.torsionPoint8) return true } @@ -103,12 +124,12 @@ func mapEdwardsToWeierstrass(p *PointAffine, out *weierstrassPointAffine) { Mul(&den, &p.X) denInv.Inverse(&den) - out.Y.Set(&curveParams.edwardsAMinusD). + out.Y.Set(&subgroupData.edwardsAMinusD). Mul(&out.Y, &num). Mul(&out.Y, &two). Mul(&out.Y, &denInv) u.Mul(&out.Y, &p.X).Mul(&u, &inv2) - out.X.Add(&u, &curveParams.weierstrassXShift) + out.X.Add(&u, &subgroupData.weierstrassXShift) } func weierstrassDouble(out, p *weierstrassPointAffine) { @@ -123,7 +144,7 @@ func weierstrassTangentSlope(lambda *fr.Element, p *weierstrassPointAffine) { var num, den fr.Element num.Square(&p.X) fr.MulBy3(&num) - num.Add(&num, &curveParams.weierstrassA) + num.Add(&num, &subgroupData.weierstrassA) den.Double(&p.Y).Inverse(&den) lambda.Mul(&num, &den) } @@ -521,10 +542,10 @@ func (p *PointAffine) IsInSubGroup() bool { return false } var l1, l2, v1, v2, z, check, tmp fr.Element - evaluateTangentLine(&l1, &r.X, &r.Y, &curveParams.torsionPoint8, &curveParams.tangentSlopeAtT8) - evaluateTangentLine(&l2, &r.X, &r.Y, &curveParams.torsionPoint4, &curveParams.tangentSlopeAtT4) - v1.Sub(&r.X, &curveParams.torsionPoint4.X) - v2.Sub(&r.X, &curveParams.torsionPoint2.X) + evaluateTangentLine(&l1, &r.X, &r.Y, &subgroupData.torsionPoint8, &subgroupData.tangentSlopeAtT8) + evaluateTangentLine(&l2, &r.X, &r.Y, &subgroupData.torsionPoint4, &subgroupData.tangentSlopeAtT4) + v1.Sub(&r.X, &subgroupData.torsionPoint4.X) + v2.Sub(&r.X, &subgroupData.torsionPoint2.X) z.Square(&l1).Square(&z) tmp.Square(&v1).Square(&tmp) z.Mul(&z, &tmp) diff --git a/internal/generator/edwards/template/curve.go.tmpl b/internal/generator/edwards/template/curve.go.tmpl index fe1ecbaf2f..0ca35a2867 100644 --- a/internal/generator/edwards/template/curve.go.tmpl +++ b/internal/generator/edwards/template/curve.go.tmpl @@ -19,26 +19,6 @@ type CurveParams struct { {{- if and (eq .Cofactor "4") .Split2Torsion}} t0, t1, b fr.Element {{- end}} - {{- if and (not .Split2Torsion) (or (eq .Cofactor "4") (eq .Cofactor "8"))}} - // edwardsAMinusD is the Edwards-model coefficient a-d used by the birational map. - edwardsAMinusD fr.Element - // weierstrassXShift is the x-translation A_M/3 from Montgomery to Weierstrass form. - weierstrassXShift fr.Element - // weierstrassA is the a-coefficient of the working short Weierstrass model. - weierstrassA fr.Element - // torsionPoint2 is the rational 2-torsion point used by the subgroup test. - torsionPoint2 weierstrassPointAffine - // torsionPoint4 is the rational 4-torsion generator used by the subgroup test. - torsionPoint4 weierstrassPointAffine - // tangentSlopeAtT4 is the tangent slope at torsionPoint4 on the working Weierstrass model. - tangentSlopeAtT4 fr.Element - {{- if eq .Cofactor "8"}} - // torsionPoint8 is the rational 8-torsion generator used by the subgroup test. - torsionPoint8 weierstrassPointAffine - // tangentSlopeAtT8 is the tangent slope at torsionPoint8 on the working Weierstrass model. - tangentSlopeAtT8 fr.Element - {{- end}} - {{- end}} {{- if .HasEndomorphism}} // endomorphism diff --git a/internal/generator/edwards/template/subgroup.go.tmpl b/internal/generator/edwards/template/subgroup.go.tmpl index 6f4ebb7deb..6e84da1a94 100644 --- a/internal/generator/edwards/template/subgroup.go.tmpl +++ b/internal/generator/edwards/template/subgroup.go.tmpl @@ -6,19 +6,42 @@ type weierstrassPointAffine struct { X, Y fr.Element } +type subgroupParams struct { + // edwardsAMinusD is the Edwards-model coefficient a-d used by the birational map. + edwardsAMinusD fr.Element + // weierstrassXShift is the x-translation A_M/3 from Montgomery to Weierstrass form. + weierstrassXShift fr.Element + // weierstrassA is the a-coefficient of the working short Weierstrass model. + weierstrassA fr.Element + // torsionPoint2 is the rational 2-torsion point used by the subgroup test. + torsionPoint2 weierstrassPointAffine + // torsionPoint4 is the rational 4-torsion generator used by the subgroup test. + torsionPoint4 weierstrassPointAffine + // tangentSlopeAtT4 is the tangent slope at torsionPoint4 on the working Weierstrass model. + tangentSlopeAtT4 fr.Element + {{- if eq .Cofactor "8"}} + // torsionPoint8 is the rational 8-torsion generator used by the subgroup test. + torsionPoint8 weierstrassPointAffine + // tangentSlopeAtT8 is the tangent slope at torsionPoint8 on the working Weierstrass model. + tangentSlopeAtT8 fr.Element + {{- end}} +} + +var subgroupData subgroupParams + func initCofactorSubgroupParams() { var three, inv3 fr.Element three.SetUint64(3) inv3.Inverse(&three) var montA, montB fr.Element - curveParams.edwardsAMinusD.Sub(&curveParams.A, &curveParams.D) + subgroupData.edwardsAMinusD.Sub(&curveParams.A, &curveParams.D) montA.Add(&curveParams.A, &curveParams.D).Double(&montA) - montB.Square(&curveParams.edwardsAMinusD) + montB.Square(&subgroupData.edwardsAMinusD) - curveParams.weierstrassXShift.Mul(&montA, &inv3) - curveParams.weierstrassA.Square(&montA).Mul(&curveParams.weierstrassA, &inv3).Neg(&curveParams.weierstrassA) - curveParams.weierstrassA.Add(&curveParams.weierstrassA, &montB) + subgroupData.weierstrassXShift.Mul(&montA, &inv3) + subgroupData.weierstrassA.Square(&montA).Mul(&subgroupData.weierstrassA, &inv3).Neg(&subgroupData.weierstrassA) + subgroupData.weierstrassA.Add(&subgroupData.weierstrassA, &montB) var sqrtA fr.Element var t4 PointAffine @@ -28,9 +51,9 @@ func initCofactorSubgroupParams() { } t4.Y.SetZero() t4.X.Inverse(&sqrtA) - mapEdwardsToWeierstrass(&t4, &curveParams.torsionPoint4) - weierstrassTangentSlope(&curveParams.tangentSlopeAtT4, &curveParams.torsionPoint4) - weierstrassDouble(&curveParams.torsionPoint2, &curveParams.torsionPoint4) + mapEdwardsToWeierstrass(&t4, &subgroupData.torsionPoint4) + weierstrassTangentSlope(&subgroupData.tangentSlopeAtT4, &subgroupData.torsionPoint4) + weierstrassDouble(&subgroupData.torsionPoint2, &subgroupData.torsionPoint4) {{- if eq .Cofactor "8"}} initCofactorEightTorsion(&t4) @@ -73,8 +96,8 @@ func initCofactorEightTorsion(t4 *PointAffine) { if !dbl.Equal(t4) { return false } - mapEdwardsToWeierstrass(&q, &curveParams.torsionPoint8) - weierstrassTangentSlope(&curveParams.tangentSlopeAtT8, &curveParams.torsionPoint8) + mapEdwardsToWeierstrass(&q, &subgroupData.torsionPoint8) + weierstrassTangentSlope(&subgroupData.tangentSlopeAtT8, &subgroupData.torsionPoint8) return true } @@ -104,12 +127,12 @@ func mapEdwardsToWeierstrass(p *PointAffine, out *weierstrassPointAffine) { Mul(&den, &p.X) denInv.Inverse(&den) - out.Y.Set(&curveParams.edwardsAMinusD). + out.Y.Set(&subgroupData.edwardsAMinusD). Mul(&out.Y, &num). Mul(&out.Y, &two). Mul(&out.Y, &denInv) u.Mul(&out.Y, &p.X).Mul(&u, &inv2) - out.X.Add(&u, &curveParams.weierstrassXShift) + out.X.Add(&u, &subgroupData.weierstrassXShift) } func weierstrassDouble(out, p *weierstrassPointAffine) { @@ -124,7 +147,7 @@ func weierstrassTangentSlope(lambda *fr.Element, p *weierstrassPointAffine) { var num, den fr.Element num.Square(&p.X) fr.MulBy3(&num) - num.Add(&num, &curveParams.weierstrassA) + num.Add(&num, &subgroupData.weierstrassA) den.Double(&p.Y).Inverse(&den) lambda.Mul(&num, &den) } @@ -239,8 +262,8 @@ func (p *PointAffine) IsInSubGroup() bool { {{- if eq .Cofactor "4"}} var l1, v1, z, check, tmp fr.Element - evaluateTangentLine(&l1, &r.X, &r.Y, &curveParams.torsionPoint4, &curveParams.tangentSlopeAtT4) - v1.Sub(&r.X, &curveParams.torsionPoint2.X) + evaluateTangentLine(&l1, &r.X, &r.Y, &subgroupData.torsionPoint4, &subgroupData.tangentSlopeAtT4) + v1.Sub(&r.X, &subgroupData.torsionPoint2.X) z.Square(&l1) tmp.Square(&v1).Mul(&tmp, &v1) z.Mul(&z, &tmp) @@ -248,10 +271,10 @@ func (p *PointAffine) IsInSubGroup() bool { return check.IsOne() {{- else if eq .Cofactor "8"}} var l1, l2, v1, v2, z, check, tmp fr.Element - evaluateTangentLine(&l1, &r.X, &r.Y, &curveParams.torsionPoint8, &curveParams.tangentSlopeAtT8) - evaluateTangentLine(&l2, &r.X, &r.Y, &curveParams.torsionPoint4, &curveParams.tangentSlopeAtT4) - v1.Sub(&r.X, &curveParams.torsionPoint4.X) - v2.Sub(&r.X, &curveParams.torsionPoint2.X) + evaluateTangentLine(&l1, &r.X, &r.Y, &subgroupData.torsionPoint8, &subgroupData.tangentSlopeAtT8) + evaluateTangentLine(&l2, &r.X, &r.Y, &subgroupData.torsionPoint4, &subgroupData.tangentSlopeAtT4) + v1.Sub(&r.X, &subgroupData.torsionPoint4.X) + v2.Sub(&r.X, &subgroupData.torsionPoint2.X) z.Square(&l1).Square(&z) tmp.Square(&v1).Square(&tmp) z.Mul(&z, &tmp) From 2663d921cc0e71473aac5fcdea7ec1ff463158bb Mon Sep 17 00:00:00 2001 From: Ivo Kubjas Date: Thu, 30 Apr 2026 12:07:14 +0000 Subject: [PATCH 4/8] test: improve test coverage --- ecc/bls12-377/twistededwards/point_test.go | 55 ++++++++ ecc/bls12-381/bandersnatch/point_test.go | 43 +++++++ ecc/bls12-381/twistededwards/point_test.go | 110 ++++++++++++++++ ecc/bls24-315/twistededwards/point_test.go | 110 ++++++++++++++++ ecc/bls24-317/twistededwards/point_test.go | 110 ++++++++++++++++ ecc/bn254/twistededwards/point_test.go | 110 ++++++++++++++++ ecc/bw6-633/twistededwards/point_test.go | 110 ++++++++++++++++ ecc/bw6-761/twistededwards/point_test.go | 110 ++++++++++++++++ .../edwards/template/tests/point.go.tmpl | 119 ++++++++++++++++++ 9 files changed, 877 insertions(+) diff --git a/ecc/bls12-377/twistededwards/point_test.go b/ecc/bls12-377/twistededwards/point_test.go index 0bf801d1fd..446139cc94 100644 --- a/ecc/bls12-377/twistededwards/point_test.go +++ b/ecc/bls12-377/twistededwards/point_test.go @@ -823,6 +823,19 @@ func TestOps(t *testing.T) { properties.TestingRun(t, gopter.ConsoleReporter(false)) } +func testSubgroupByOrder(p *PointAffine) bool { + params := GetEdwardsCurve() + var check PointAffine + check.ScalarMultiplication(p, ¶ms.Order) + return check.IsZero() +} + +func testRejectTorsionCoset(p, torsion *PointAffine) bool { + var q PointAffine + q.Add(p, torsion) + return !q.IsInSubGroup() && !testSubgroupByOrder(&q) +} + func TestIsInSubGroup(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() @@ -866,6 +879,48 @@ func TestIsInSubGroup(t *testing.T) { genS, )) + properties.Property("IsInSubGroup should agree with multiplication by subgroup order on subgroup points", prop.ForAll( + func(s big.Int) bool { + params := GetEdwardsCurve() + + var p PointAffine + p.ScalarMultiplication(¶ms.Base, &s) + + return p.IsInSubGroup() == testSubgroupByOrder(&p) + }, + genS, + )) + + properties.Property("Torsion cosets should not be in subgroup", prop.ForAll( + func(s big.Int) bool { + params := GetEdwardsCurve() + + var p PointAffine + p.ScalarMultiplication(¶ms.Base, &s) + + var t2 PointAffine + t2.Y.SetOne().Neg(&t2.Y) + if !testRejectTorsionCoset(&p, &t2) { + return false + } + initOnce.Do(initCurveParams) + var sqrtA fr.Element + sqrtA.Set(&curveParams.A) + if sqrtA.Sqrt(&sqrtA) == nil { + return false + } + var t4 PointAffine + t4.Y.SetZero() + t4.X.Inverse(&sqrtA) + if !testRejectTorsionCoset(&p, &t4) { + return false + } + + return true + }, + genS, + )) + properties.TestingRun(t, gopter.ConsoleReporter(false)) } diff --git a/ecc/bls12-381/bandersnatch/point_test.go b/ecc/bls12-381/bandersnatch/point_test.go index ce5d394617..4c2e5f00c9 100644 --- a/ecc/bls12-381/bandersnatch/point_test.go +++ b/ecc/bls12-381/bandersnatch/point_test.go @@ -855,6 +855,19 @@ func TestOps(t *testing.T) { properties.TestingRun(t, gopter.ConsoleReporter(false)) } +func testSubgroupByOrder(p *PointAffine) bool { + params := GetEdwardsCurve() + var check PointAffine + check.ScalarMultiplication(p, ¶ms.Order) + return check.IsZero() +} + +func testRejectTorsionCoset(p, torsion *PointAffine) bool { + var q PointAffine + q.Add(p, torsion) + return !q.IsInSubGroup() && !testSubgroupByOrder(&q) +} + func TestIsInSubGroup(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() @@ -898,6 +911,36 @@ func TestIsInSubGroup(t *testing.T) { genS, )) + properties.Property("IsInSubGroup should agree with multiplication by subgroup order on subgroup points", prop.ForAll( + func(s big.Int) bool { + params := GetEdwardsCurve() + + var p PointAffine + p.ScalarMultiplication(¶ms.Base, &s) + + return p.IsInSubGroup() == testSubgroupByOrder(&p) + }, + genS, + )) + + properties.Property("Torsion cosets should not be in subgroup", prop.ForAll( + func(s big.Int) bool { + params := GetEdwardsCurve() + + var p PointAffine + p.ScalarMultiplication(¶ms.Base, &s) + + var t2 PointAffine + t2.Y.SetOne().Neg(&t2.Y) + if !testRejectTorsionCoset(&p, &t2) { + return false + } + + return true + }, + genS, + )) + properties.TestingRun(t, gopter.ConsoleReporter(false)) } diff --git a/ecc/bls12-381/twistededwards/point_test.go b/ecc/bls12-381/twistededwards/point_test.go index 574cf1de04..e65a319809 100644 --- a/ecc/bls12-381/twistededwards/point_test.go +++ b/ecc/bls12-381/twistededwards/point_test.go @@ -823,6 +823,70 @@ func TestOps(t *testing.T) { properties.TestingRun(t, gopter.ConsoleReporter(false)) } +func testSubgroupByOrder(p *PointAffine) bool { + params := GetEdwardsCurve() + var check PointAffine + check.ScalarMultiplication(p, ¶ms.Order) + return check.IsZero() +} + +func testRejectTorsionCoset(p, torsion *PointAffine) bool { + var q PointAffine + q.Add(p, torsion) + return !q.IsInSubGroup() && !testSubgroupByOrder(&q) +} +func testTorsion8Point(t4 *PointAffine) (PointAffine, bool) { + initOnce.Do(initCurveParams) + var one, aInv, discr, discrSqrt, x2, y2, t fr.Element + one.SetOne() + aInv.Inverse(&curveParams.A) + discr.Set(&curveParams.D).Neg(&discr).Mul(&discr, &aInv).Add(&discr, &one) + if discrSqrt.Sqrt(&discr) == nil { + return PointAffine{}, false + } + + var dInv fr.Element + dInv.Inverse(&curveParams.D) + tryT8 := func(root *fr.Element, negateY, negateX bool) (PointAffine, bool) { + var q, dbl PointAffine + t.Add(&one, root). + Mul(&t, &curveParams.A). + Mul(&t, &dInv) + if y2.Sqrt(&t) == nil { + return PointAffine{}, false + } + if negateY { + y2.Neg(&y2) + } + x2.Mul(&t, &aInv) + if q.X.Sqrt(&x2) == nil { + return PointAffine{}, false + } + if negateX { + q.X.Neg(&q.X) + } + q.Y.Set(&y2) + dbl.Double(&q) + if !dbl.Equal(t4) { + return PointAffine{}, false + } + return q, true + } + + roots := [2]fr.Element{discrSqrt} + roots[1].Neg(&discrSqrt) + for i := range roots { + for _, negateY := range []bool{false, true} { + for _, negateX := range []bool{false, true} { + if q, ok := tryT8(&roots[i], negateY, negateX); ok { + return q, true + } + } + } + } + return PointAffine{}, false +} + func TestIsInSubGroup(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() @@ -866,6 +930,52 @@ func TestIsInSubGroup(t *testing.T) { genS, )) + properties.Property("IsInSubGroup should agree with multiplication by subgroup order on subgroup points", prop.ForAll( + func(s big.Int) bool { + params := GetEdwardsCurve() + + var p PointAffine + p.ScalarMultiplication(¶ms.Base, &s) + + return p.IsInSubGroup() == testSubgroupByOrder(&p) + }, + genS, + )) + + properties.Property("Torsion cosets should not be in subgroup", prop.ForAll( + func(s big.Int) bool { + params := GetEdwardsCurve() + + var p PointAffine + p.ScalarMultiplication(¶ms.Base, &s) + + var t2 PointAffine + t2.Y.SetOne().Neg(&t2.Y) + if !testRejectTorsionCoset(&p, &t2) { + return false + } + initOnce.Do(initCurveParams) + var sqrtA fr.Element + sqrtA.Set(&curveParams.A) + if sqrtA.Sqrt(&sqrtA) == nil { + return false + } + var t4 PointAffine + t4.Y.SetZero() + t4.X.Inverse(&sqrtA) + if !testRejectTorsionCoset(&p, &t4) { + return false + } + t8, ok := testTorsion8Point(&t4) + if !ok || !testRejectTorsionCoset(&p, &t8) { + return false + } + + return true + }, + genS, + )) + properties.TestingRun(t, gopter.ConsoleReporter(false)) } diff --git a/ecc/bls24-315/twistededwards/point_test.go b/ecc/bls24-315/twistededwards/point_test.go index 0a7cd06243..570dee71a7 100644 --- a/ecc/bls24-315/twistededwards/point_test.go +++ b/ecc/bls24-315/twistededwards/point_test.go @@ -823,6 +823,70 @@ func TestOps(t *testing.T) { properties.TestingRun(t, gopter.ConsoleReporter(false)) } +func testSubgroupByOrder(p *PointAffine) bool { + params := GetEdwardsCurve() + var check PointAffine + check.ScalarMultiplication(p, ¶ms.Order) + return check.IsZero() +} + +func testRejectTorsionCoset(p, torsion *PointAffine) bool { + var q PointAffine + q.Add(p, torsion) + return !q.IsInSubGroup() && !testSubgroupByOrder(&q) +} +func testTorsion8Point(t4 *PointAffine) (PointAffine, bool) { + initOnce.Do(initCurveParams) + var one, aInv, discr, discrSqrt, x2, y2, t fr.Element + one.SetOne() + aInv.Inverse(&curveParams.A) + discr.Set(&curveParams.D).Neg(&discr).Mul(&discr, &aInv).Add(&discr, &one) + if discrSqrt.Sqrt(&discr) == nil { + return PointAffine{}, false + } + + var dInv fr.Element + dInv.Inverse(&curveParams.D) + tryT8 := func(root *fr.Element, negateY, negateX bool) (PointAffine, bool) { + var q, dbl PointAffine + t.Add(&one, root). + Mul(&t, &curveParams.A). + Mul(&t, &dInv) + if y2.Sqrt(&t) == nil { + return PointAffine{}, false + } + if negateY { + y2.Neg(&y2) + } + x2.Mul(&t, &aInv) + if q.X.Sqrt(&x2) == nil { + return PointAffine{}, false + } + if negateX { + q.X.Neg(&q.X) + } + q.Y.Set(&y2) + dbl.Double(&q) + if !dbl.Equal(t4) { + return PointAffine{}, false + } + return q, true + } + + roots := [2]fr.Element{discrSqrt} + roots[1].Neg(&discrSqrt) + for i := range roots { + for _, negateY := range []bool{false, true} { + for _, negateX := range []bool{false, true} { + if q, ok := tryT8(&roots[i], negateY, negateX); ok { + return q, true + } + } + } + } + return PointAffine{}, false +} + func TestIsInSubGroup(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() @@ -866,6 +930,52 @@ func TestIsInSubGroup(t *testing.T) { genS, )) + properties.Property("IsInSubGroup should agree with multiplication by subgroup order on subgroup points", prop.ForAll( + func(s big.Int) bool { + params := GetEdwardsCurve() + + var p PointAffine + p.ScalarMultiplication(¶ms.Base, &s) + + return p.IsInSubGroup() == testSubgroupByOrder(&p) + }, + genS, + )) + + properties.Property("Torsion cosets should not be in subgroup", prop.ForAll( + func(s big.Int) bool { + params := GetEdwardsCurve() + + var p PointAffine + p.ScalarMultiplication(¶ms.Base, &s) + + var t2 PointAffine + t2.Y.SetOne().Neg(&t2.Y) + if !testRejectTorsionCoset(&p, &t2) { + return false + } + initOnce.Do(initCurveParams) + var sqrtA fr.Element + sqrtA.Set(&curveParams.A) + if sqrtA.Sqrt(&sqrtA) == nil { + return false + } + var t4 PointAffine + t4.Y.SetZero() + t4.X.Inverse(&sqrtA) + if !testRejectTorsionCoset(&p, &t4) { + return false + } + t8, ok := testTorsion8Point(&t4) + if !ok || !testRejectTorsionCoset(&p, &t8) { + return false + } + + return true + }, + genS, + )) + properties.TestingRun(t, gopter.ConsoleReporter(false)) } diff --git a/ecc/bls24-317/twistededwards/point_test.go b/ecc/bls24-317/twistededwards/point_test.go index e45389adba..b3fb237954 100644 --- a/ecc/bls24-317/twistededwards/point_test.go +++ b/ecc/bls24-317/twistededwards/point_test.go @@ -823,6 +823,70 @@ func TestOps(t *testing.T) { properties.TestingRun(t, gopter.ConsoleReporter(false)) } +func testSubgroupByOrder(p *PointAffine) bool { + params := GetEdwardsCurve() + var check PointAffine + check.ScalarMultiplication(p, ¶ms.Order) + return check.IsZero() +} + +func testRejectTorsionCoset(p, torsion *PointAffine) bool { + var q PointAffine + q.Add(p, torsion) + return !q.IsInSubGroup() && !testSubgroupByOrder(&q) +} +func testTorsion8Point(t4 *PointAffine) (PointAffine, bool) { + initOnce.Do(initCurveParams) + var one, aInv, discr, discrSqrt, x2, y2, t fr.Element + one.SetOne() + aInv.Inverse(&curveParams.A) + discr.Set(&curveParams.D).Neg(&discr).Mul(&discr, &aInv).Add(&discr, &one) + if discrSqrt.Sqrt(&discr) == nil { + return PointAffine{}, false + } + + var dInv fr.Element + dInv.Inverse(&curveParams.D) + tryT8 := func(root *fr.Element, negateY, negateX bool) (PointAffine, bool) { + var q, dbl PointAffine + t.Add(&one, root). + Mul(&t, &curveParams.A). + Mul(&t, &dInv) + if y2.Sqrt(&t) == nil { + return PointAffine{}, false + } + if negateY { + y2.Neg(&y2) + } + x2.Mul(&t, &aInv) + if q.X.Sqrt(&x2) == nil { + return PointAffine{}, false + } + if negateX { + q.X.Neg(&q.X) + } + q.Y.Set(&y2) + dbl.Double(&q) + if !dbl.Equal(t4) { + return PointAffine{}, false + } + return q, true + } + + roots := [2]fr.Element{discrSqrt} + roots[1].Neg(&discrSqrt) + for i := range roots { + for _, negateY := range []bool{false, true} { + for _, negateX := range []bool{false, true} { + if q, ok := tryT8(&roots[i], negateY, negateX); ok { + return q, true + } + } + } + } + return PointAffine{}, false +} + func TestIsInSubGroup(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() @@ -866,6 +930,52 @@ func TestIsInSubGroup(t *testing.T) { genS, )) + properties.Property("IsInSubGroup should agree with multiplication by subgroup order on subgroup points", prop.ForAll( + func(s big.Int) bool { + params := GetEdwardsCurve() + + var p PointAffine + p.ScalarMultiplication(¶ms.Base, &s) + + return p.IsInSubGroup() == testSubgroupByOrder(&p) + }, + genS, + )) + + properties.Property("Torsion cosets should not be in subgroup", prop.ForAll( + func(s big.Int) bool { + params := GetEdwardsCurve() + + var p PointAffine + p.ScalarMultiplication(¶ms.Base, &s) + + var t2 PointAffine + t2.Y.SetOne().Neg(&t2.Y) + if !testRejectTorsionCoset(&p, &t2) { + return false + } + initOnce.Do(initCurveParams) + var sqrtA fr.Element + sqrtA.Set(&curveParams.A) + if sqrtA.Sqrt(&sqrtA) == nil { + return false + } + var t4 PointAffine + t4.Y.SetZero() + t4.X.Inverse(&sqrtA) + if !testRejectTorsionCoset(&p, &t4) { + return false + } + t8, ok := testTorsion8Point(&t4) + if !ok || !testRejectTorsionCoset(&p, &t8) { + return false + } + + return true + }, + genS, + )) + properties.TestingRun(t, gopter.ConsoleReporter(false)) } diff --git a/ecc/bn254/twistededwards/point_test.go b/ecc/bn254/twistededwards/point_test.go index 0c6301c4d0..b8172e2171 100644 --- a/ecc/bn254/twistededwards/point_test.go +++ b/ecc/bn254/twistededwards/point_test.go @@ -823,6 +823,70 @@ func TestOps(t *testing.T) { properties.TestingRun(t, gopter.ConsoleReporter(false)) } +func testSubgroupByOrder(p *PointAffine) bool { + params := GetEdwardsCurve() + var check PointAffine + check.ScalarMultiplication(p, ¶ms.Order) + return check.IsZero() +} + +func testRejectTorsionCoset(p, torsion *PointAffine) bool { + var q PointAffine + q.Add(p, torsion) + return !q.IsInSubGroup() && !testSubgroupByOrder(&q) +} +func testTorsion8Point(t4 *PointAffine) (PointAffine, bool) { + initOnce.Do(initCurveParams) + var one, aInv, discr, discrSqrt, x2, y2, t fr.Element + one.SetOne() + aInv.Inverse(&curveParams.A) + discr.Set(&curveParams.D).Neg(&discr).Mul(&discr, &aInv).Add(&discr, &one) + if discrSqrt.Sqrt(&discr) == nil { + return PointAffine{}, false + } + + var dInv fr.Element + dInv.Inverse(&curveParams.D) + tryT8 := func(root *fr.Element, negateY, negateX bool) (PointAffine, bool) { + var q, dbl PointAffine + t.Add(&one, root). + Mul(&t, &curveParams.A). + Mul(&t, &dInv) + if y2.Sqrt(&t) == nil { + return PointAffine{}, false + } + if negateY { + y2.Neg(&y2) + } + x2.Mul(&t, &aInv) + if q.X.Sqrt(&x2) == nil { + return PointAffine{}, false + } + if negateX { + q.X.Neg(&q.X) + } + q.Y.Set(&y2) + dbl.Double(&q) + if !dbl.Equal(t4) { + return PointAffine{}, false + } + return q, true + } + + roots := [2]fr.Element{discrSqrt} + roots[1].Neg(&discrSqrt) + for i := range roots { + for _, negateY := range []bool{false, true} { + for _, negateX := range []bool{false, true} { + if q, ok := tryT8(&roots[i], negateY, negateX); ok { + return q, true + } + } + } + } + return PointAffine{}, false +} + func TestIsInSubGroup(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() @@ -866,6 +930,52 @@ func TestIsInSubGroup(t *testing.T) { genS, )) + properties.Property("IsInSubGroup should agree with multiplication by subgroup order on subgroup points", prop.ForAll( + func(s big.Int) bool { + params := GetEdwardsCurve() + + var p PointAffine + p.ScalarMultiplication(¶ms.Base, &s) + + return p.IsInSubGroup() == testSubgroupByOrder(&p) + }, + genS, + )) + + properties.Property("Torsion cosets should not be in subgroup", prop.ForAll( + func(s big.Int) bool { + params := GetEdwardsCurve() + + var p PointAffine + p.ScalarMultiplication(¶ms.Base, &s) + + var t2 PointAffine + t2.Y.SetOne().Neg(&t2.Y) + if !testRejectTorsionCoset(&p, &t2) { + return false + } + initOnce.Do(initCurveParams) + var sqrtA fr.Element + sqrtA.Set(&curveParams.A) + if sqrtA.Sqrt(&sqrtA) == nil { + return false + } + var t4 PointAffine + t4.Y.SetZero() + t4.X.Inverse(&sqrtA) + if !testRejectTorsionCoset(&p, &t4) { + return false + } + t8, ok := testTorsion8Point(&t4) + if !ok || !testRejectTorsionCoset(&p, &t8) { + return false + } + + return true + }, + genS, + )) + properties.TestingRun(t, gopter.ConsoleReporter(false)) } diff --git a/ecc/bw6-633/twistededwards/point_test.go b/ecc/bw6-633/twistededwards/point_test.go index 2b30d29bd7..4286b5f707 100644 --- a/ecc/bw6-633/twistededwards/point_test.go +++ b/ecc/bw6-633/twistededwards/point_test.go @@ -823,6 +823,70 @@ func TestOps(t *testing.T) { properties.TestingRun(t, gopter.ConsoleReporter(false)) } +func testSubgroupByOrder(p *PointAffine) bool { + params := GetEdwardsCurve() + var check PointAffine + check.ScalarMultiplication(p, ¶ms.Order) + return check.IsZero() +} + +func testRejectTorsionCoset(p, torsion *PointAffine) bool { + var q PointAffine + q.Add(p, torsion) + return !q.IsInSubGroup() && !testSubgroupByOrder(&q) +} +func testTorsion8Point(t4 *PointAffine) (PointAffine, bool) { + initOnce.Do(initCurveParams) + var one, aInv, discr, discrSqrt, x2, y2, t fr.Element + one.SetOne() + aInv.Inverse(&curveParams.A) + discr.Set(&curveParams.D).Neg(&discr).Mul(&discr, &aInv).Add(&discr, &one) + if discrSqrt.Sqrt(&discr) == nil { + return PointAffine{}, false + } + + var dInv fr.Element + dInv.Inverse(&curveParams.D) + tryT8 := func(root *fr.Element, negateY, negateX bool) (PointAffine, bool) { + var q, dbl PointAffine + t.Add(&one, root). + Mul(&t, &curveParams.A). + Mul(&t, &dInv) + if y2.Sqrt(&t) == nil { + return PointAffine{}, false + } + if negateY { + y2.Neg(&y2) + } + x2.Mul(&t, &aInv) + if q.X.Sqrt(&x2) == nil { + return PointAffine{}, false + } + if negateX { + q.X.Neg(&q.X) + } + q.Y.Set(&y2) + dbl.Double(&q) + if !dbl.Equal(t4) { + return PointAffine{}, false + } + return q, true + } + + roots := [2]fr.Element{discrSqrt} + roots[1].Neg(&discrSqrt) + for i := range roots { + for _, negateY := range []bool{false, true} { + for _, negateX := range []bool{false, true} { + if q, ok := tryT8(&roots[i], negateY, negateX); ok { + return q, true + } + } + } + } + return PointAffine{}, false +} + func TestIsInSubGroup(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() @@ -866,6 +930,52 @@ func TestIsInSubGroup(t *testing.T) { genS, )) + properties.Property("IsInSubGroup should agree with multiplication by subgroup order on subgroup points", prop.ForAll( + func(s big.Int) bool { + params := GetEdwardsCurve() + + var p PointAffine + p.ScalarMultiplication(¶ms.Base, &s) + + return p.IsInSubGroup() == testSubgroupByOrder(&p) + }, + genS, + )) + + properties.Property("Torsion cosets should not be in subgroup", prop.ForAll( + func(s big.Int) bool { + params := GetEdwardsCurve() + + var p PointAffine + p.ScalarMultiplication(¶ms.Base, &s) + + var t2 PointAffine + t2.Y.SetOne().Neg(&t2.Y) + if !testRejectTorsionCoset(&p, &t2) { + return false + } + initOnce.Do(initCurveParams) + var sqrtA fr.Element + sqrtA.Set(&curveParams.A) + if sqrtA.Sqrt(&sqrtA) == nil { + return false + } + var t4 PointAffine + t4.Y.SetZero() + t4.X.Inverse(&sqrtA) + if !testRejectTorsionCoset(&p, &t4) { + return false + } + t8, ok := testTorsion8Point(&t4) + if !ok || !testRejectTorsionCoset(&p, &t8) { + return false + } + + return true + }, + genS, + )) + properties.TestingRun(t, gopter.ConsoleReporter(false)) } diff --git a/ecc/bw6-761/twistededwards/point_test.go b/ecc/bw6-761/twistededwards/point_test.go index 3efb32d4bc..87cdc3bbd7 100644 --- a/ecc/bw6-761/twistededwards/point_test.go +++ b/ecc/bw6-761/twistededwards/point_test.go @@ -823,6 +823,70 @@ func TestOps(t *testing.T) { properties.TestingRun(t, gopter.ConsoleReporter(false)) } +func testSubgroupByOrder(p *PointAffine) bool { + params := GetEdwardsCurve() + var check PointAffine + check.ScalarMultiplication(p, ¶ms.Order) + return check.IsZero() +} + +func testRejectTorsionCoset(p, torsion *PointAffine) bool { + var q PointAffine + q.Add(p, torsion) + return !q.IsInSubGroup() && !testSubgroupByOrder(&q) +} +func testTorsion8Point(t4 *PointAffine) (PointAffine, bool) { + initOnce.Do(initCurveParams) + var one, aInv, discr, discrSqrt, x2, y2, t fr.Element + one.SetOne() + aInv.Inverse(&curveParams.A) + discr.Set(&curveParams.D).Neg(&discr).Mul(&discr, &aInv).Add(&discr, &one) + if discrSqrt.Sqrt(&discr) == nil { + return PointAffine{}, false + } + + var dInv fr.Element + dInv.Inverse(&curveParams.D) + tryT8 := func(root *fr.Element, negateY, negateX bool) (PointAffine, bool) { + var q, dbl PointAffine + t.Add(&one, root). + Mul(&t, &curveParams.A). + Mul(&t, &dInv) + if y2.Sqrt(&t) == nil { + return PointAffine{}, false + } + if negateY { + y2.Neg(&y2) + } + x2.Mul(&t, &aInv) + if q.X.Sqrt(&x2) == nil { + return PointAffine{}, false + } + if negateX { + q.X.Neg(&q.X) + } + q.Y.Set(&y2) + dbl.Double(&q) + if !dbl.Equal(t4) { + return PointAffine{}, false + } + return q, true + } + + roots := [2]fr.Element{discrSqrt} + roots[1].Neg(&discrSqrt) + for i := range roots { + for _, negateY := range []bool{false, true} { + for _, negateX := range []bool{false, true} { + if q, ok := tryT8(&roots[i], negateY, negateX); ok { + return q, true + } + } + } + } + return PointAffine{}, false +} + func TestIsInSubGroup(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() @@ -866,6 +930,52 @@ func TestIsInSubGroup(t *testing.T) { genS, )) + properties.Property("IsInSubGroup should agree with multiplication by subgroup order on subgroup points", prop.ForAll( + func(s big.Int) bool { + params := GetEdwardsCurve() + + var p PointAffine + p.ScalarMultiplication(¶ms.Base, &s) + + return p.IsInSubGroup() == testSubgroupByOrder(&p) + }, + genS, + )) + + properties.Property("Torsion cosets should not be in subgroup", prop.ForAll( + func(s big.Int) bool { + params := GetEdwardsCurve() + + var p PointAffine + p.ScalarMultiplication(¶ms.Base, &s) + + var t2 PointAffine + t2.Y.SetOne().Neg(&t2.Y) + if !testRejectTorsionCoset(&p, &t2) { + return false + } + initOnce.Do(initCurveParams) + var sqrtA fr.Element + sqrtA.Set(&curveParams.A) + if sqrtA.Sqrt(&sqrtA) == nil { + return false + } + var t4 PointAffine + t4.Y.SetZero() + t4.X.Inverse(&sqrtA) + if !testRejectTorsionCoset(&p, &t4) { + return false + } + t8, ok := testTorsion8Point(&t4) + if !ok || !testRejectTorsionCoset(&p, &t8) { + return false + } + + return true + }, + genS, + )) + properties.TestingRun(t, gopter.ConsoleReporter(false)) } diff --git a/internal/generator/edwards/template/tests/point.go.tmpl b/internal/generator/edwards/template/tests/point.go.tmpl index b9f3e04c6a..4a0ef12d54 100644 --- a/internal/generator/edwards/template/tests/point.go.tmpl +++ b/internal/generator/edwards/template/tests/point.go.tmpl @@ -861,6 +861,73 @@ func TestOps(t *testing.T) { } {{- if or (eq .Cofactor "4") (eq .Cofactor "8")}} +func testSubgroupByOrder(p *PointAffine) bool { + params := GetEdwardsCurve() + var check PointAffine + check.ScalarMultiplication(p, ¶ms.Order) + return check.IsZero() +} + +func testRejectTorsionCoset(p, torsion *PointAffine) bool { + var q PointAffine + q.Add(p, torsion) + return !q.IsInSubGroup() && !testSubgroupByOrder(&q) +} + +{{- if and (not .Split2Torsion) (eq .Cofactor "8")}} +func testTorsion8Point(t4 *PointAffine) (PointAffine, bool) { + initOnce.Do(initCurveParams) + var one, aInv, discr, discrSqrt, x2, y2, t fr.Element + one.SetOne() + aInv.Inverse(&curveParams.A) + discr.Set(&curveParams.D).Neg(&discr).Mul(&discr, &aInv).Add(&discr, &one) + if discrSqrt.Sqrt(&discr) == nil { + return PointAffine{}, false + } + + var dInv fr.Element + dInv.Inverse(&curveParams.D) + tryT8 := func(root *fr.Element, negateY, negateX bool) (PointAffine, bool) { + var q, dbl PointAffine + t.Add(&one, root). + Mul(&t, &curveParams.A). + Mul(&t, &dInv) + if y2.Sqrt(&t) == nil { + return PointAffine{}, false + } + if negateY { + y2.Neg(&y2) + } + x2.Mul(&t, &aInv) + if q.X.Sqrt(&x2) == nil { + return PointAffine{}, false + } + if negateX { + q.X.Neg(&q.X) + } + q.Y.Set(&y2) + dbl.Double(&q) + if !dbl.Equal(t4) { + return PointAffine{}, false + } + return q, true + } + + roots := [2]fr.Element{discrSqrt} + roots[1].Neg(&discrSqrt) + for i := range roots { + for _, negateY := range []bool{false, true} { + for _, negateX := range []bool{false, true} { + if q, ok := tryT8(&roots[i], negateY, negateX); ok { + return q, true + } + } + } + } + return PointAffine{}, false +} +{{- end}} + func TestIsInSubGroup(t *testing.T) { t.Parallel() parameters := gopter.DefaultTestParameters() @@ -904,6 +971,58 @@ func TestIsInSubGroup(t *testing.T) { genS, )) + properties.Property("IsInSubGroup should agree with multiplication by subgroup order on subgroup points", prop.ForAll( + func(s big.Int) bool { + params := GetEdwardsCurve() + + var p PointAffine + p.ScalarMultiplication(¶ms.Base, &s) + + return p.IsInSubGroup() == testSubgroupByOrder(&p) + }, + genS, + )) + + properties.Property("Torsion cosets should not be in subgroup", prop.ForAll( + func(s big.Int) bool { + params := GetEdwardsCurve() + + var p PointAffine + p.ScalarMultiplication(¶ms.Base, &s) + + var t2 PointAffine + t2.Y.SetOne().Neg(&t2.Y) + if !testRejectTorsionCoset(&p, &t2) { + return false + } + + {{- if not .Split2Torsion}} + initOnce.Do(initCurveParams) + var sqrtA fr.Element + sqrtA.Set(&curveParams.A) + if sqrtA.Sqrt(&sqrtA) == nil { + return false + } + var t4 PointAffine + t4.Y.SetZero() + t4.X.Inverse(&sqrtA) + if !testRejectTorsionCoset(&p, &t4) { + return false + } + + {{- if eq .Cofactor "8"}} + t8, ok := testTorsion8Point(&t4) + if !ok || !testRejectTorsionCoset(&p, &t8) { + return false + } + {{- end}} + {{- end}} + + return true + }, + genS, + )) + properties.TestingRun(t, gopter.ConsoleReporter(false)) } {{- end}} From fe6a6081cf26a903b4c971f1f12479544ffacd5c Mon Sep 17 00:00:00 2001 From: Ivo Kubjas Date: Thu, 30 Apr 2026 12:30:43 +0000 Subject: [PATCH 5/8] fix: staticcheck --- ecc/bls12-377/twistededwards/point_test.go | 4 ++-- ecc/bls12-381/bandersnatch/point_test.go | 2 +- ecc/bls12-381/twistededwards/point_test.go | 4 ++-- ecc/bls24-315/twistededwards/point_test.go | 4 ++-- ecc/bls24-317/twistededwards/point_test.go | 4 ++-- ecc/bn254/twistededwards/point_test.go | 4 ++-- ecc/bw6-633/twistededwards/point_test.go | 4 ++-- ecc/bw6-761/twistededwards/point_test.go | 4 ++-- internal/generator/edwards/template/tests/point.go.tmpl | 4 ++-- 9 files changed, 17 insertions(+), 17 deletions(-) diff --git a/ecc/bls12-377/twistededwards/point_test.go b/ecc/bls12-377/twistededwards/point_test.go index 446139cc94..45df2abce7 100644 --- a/ecc/bls12-377/twistededwards/point_test.go +++ b/ecc/bls12-377/twistededwards/point_test.go @@ -900,7 +900,7 @@ func TestIsInSubGroup(t *testing.T) { var t2 PointAffine t2.Y.SetOne().Neg(&t2.Y) - if !testRejectTorsionCoset(&p, &t2) { + if !testRejectTorsionCoset(&p, &t2) { //nolint: staticcheck, we code generate and in some paths we don't return early return false } initOnce.Do(initCurveParams) @@ -912,7 +912,7 @@ func TestIsInSubGroup(t *testing.T) { var t4 PointAffine t4.Y.SetZero() t4.X.Inverse(&sqrtA) - if !testRejectTorsionCoset(&p, &t4) { + if !testRejectTorsionCoset(&p, &t4) { //nolint: staticcheck, we code generate and in some paths we don't return early return false } diff --git a/ecc/bls12-381/bandersnatch/point_test.go b/ecc/bls12-381/bandersnatch/point_test.go index 4c2e5f00c9..8c063e3718 100644 --- a/ecc/bls12-381/bandersnatch/point_test.go +++ b/ecc/bls12-381/bandersnatch/point_test.go @@ -932,7 +932,7 @@ func TestIsInSubGroup(t *testing.T) { var t2 PointAffine t2.Y.SetOne().Neg(&t2.Y) - if !testRejectTorsionCoset(&p, &t2) { + if !testRejectTorsionCoset(&p, &t2) { //nolint: staticcheck, we code generate and in some paths we don't return early return false } diff --git a/ecc/bls12-381/twistededwards/point_test.go b/ecc/bls12-381/twistededwards/point_test.go index e65a319809..f100f80bca 100644 --- a/ecc/bls12-381/twistededwards/point_test.go +++ b/ecc/bls12-381/twistededwards/point_test.go @@ -951,7 +951,7 @@ func TestIsInSubGroup(t *testing.T) { var t2 PointAffine t2.Y.SetOne().Neg(&t2.Y) - if !testRejectTorsionCoset(&p, &t2) { + if !testRejectTorsionCoset(&p, &t2) { //nolint: staticcheck, we code generate and in some paths we don't return early return false } initOnce.Do(initCurveParams) @@ -963,7 +963,7 @@ func TestIsInSubGroup(t *testing.T) { var t4 PointAffine t4.Y.SetZero() t4.X.Inverse(&sqrtA) - if !testRejectTorsionCoset(&p, &t4) { + if !testRejectTorsionCoset(&p, &t4) { //nolint: staticcheck, we code generate and in some paths we don't return early return false } t8, ok := testTorsion8Point(&t4) diff --git a/ecc/bls24-315/twistededwards/point_test.go b/ecc/bls24-315/twistededwards/point_test.go index 570dee71a7..8a819c5fc0 100644 --- a/ecc/bls24-315/twistededwards/point_test.go +++ b/ecc/bls24-315/twistededwards/point_test.go @@ -951,7 +951,7 @@ func TestIsInSubGroup(t *testing.T) { var t2 PointAffine t2.Y.SetOne().Neg(&t2.Y) - if !testRejectTorsionCoset(&p, &t2) { + if !testRejectTorsionCoset(&p, &t2) { //nolint: staticcheck, we code generate and in some paths we don't return early return false } initOnce.Do(initCurveParams) @@ -963,7 +963,7 @@ func TestIsInSubGroup(t *testing.T) { var t4 PointAffine t4.Y.SetZero() t4.X.Inverse(&sqrtA) - if !testRejectTorsionCoset(&p, &t4) { + if !testRejectTorsionCoset(&p, &t4) { //nolint: staticcheck, we code generate and in some paths we don't return early return false } t8, ok := testTorsion8Point(&t4) diff --git a/ecc/bls24-317/twistededwards/point_test.go b/ecc/bls24-317/twistededwards/point_test.go index b3fb237954..848f4648eb 100644 --- a/ecc/bls24-317/twistededwards/point_test.go +++ b/ecc/bls24-317/twistededwards/point_test.go @@ -951,7 +951,7 @@ func TestIsInSubGroup(t *testing.T) { var t2 PointAffine t2.Y.SetOne().Neg(&t2.Y) - if !testRejectTorsionCoset(&p, &t2) { + if !testRejectTorsionCoset(&p, &t2) { //nolint: staticcheck, we code generate and in some paths we don't return early return false } initOnce.Do(initCurveParams) @@ -963,7 +963,7 @@ func TestIsInSubGroup(t *testing.T) { var t4 PointAffine t4.Y.SetZero() t4.X.Inverse(&sqrtA) - if !testRejectTorsionCoset(&p, &t4) { + if !testRejectTorsionCoset(&p, &t4) { //nolint: staticcheck, we code generate and in some paths we don't return early return false } t8, ok := testTorsion8Point(&t4) diff --git a/ecc/bn254/twistededwards/point_test.go b/ecc/bn254/twistededwards/point_test.go index b8172e2171..66a1c841cc 100644 --- a/ecc/bn254/twistededwards/point_test.go +++ b/ecc/bn254/twistededwards/point_test.go @@ -951,7 +951,7 @@ func TestIsInSubGroup(t *testing.T) { var t2 PointAffine t2.Y.SetOne().Neg(&t2.Y) - if !testRejectTorsionCoset(&p, &t2) { + if !testRejectTorsionCoset(&p, &t2) { //nolint: staticcheck, we code generate and in some paths we don't return early return false } initOnce.Do(initCurveParams) @@ -963,7 +963,7 @@ func TestIsInSubGroup(t *testing.T) { var t4 PointAffine t4.Y.SetZero() t4.X.Inverse(&sqrtA) - if !testRejectTorsionCoset(&p, &t4) { + if !testRejectTorsionCoset(&p, &t4) { //nolint: staticcheck, we code generate and in some paths we don't return early return false } t8, ok := testTorsion8Point(&t4) diff --git a/ecc/bw6-633/twistededwards/point_test.go b/ecc/bw6-633/twistededwards/point_test.go index 4286b5f707..5aa530ffe8 100644 --- a/ecc/bw6-633/twistededwards/point_test.go +++ b/ecc/bw6-633/twistededwards/point_test.go @@ -951,7 +951,7 @@ func TestIsInSubGroup(t *testing.T) { var t2 PointAffine t2.Y.SetOne().Neg(&t2.Y) - if !testRejectTorsionCoset(&p, &t2) { + if !testRejectTorsionCoset(&p, &t2) { //nolint: staticcheck, we code generate and in some paths we don't return early return false } initOnce.Do(initCurveParams) @@ -963,7 +963,7 @@ func TestIsInSubGroup(t *testing.T) { var t4 PointAffine t4.Y.SetZero() t4.X.Inverse(&sqrtA) - if !testRejectTorsionCoset(&p, &t4) { + if !testRejectTorsionCoset(&p, &t4) { //nolint: staticcheck, we code generate and in some paths we don't return early return false } t8, ok := testTorsion8Point(&t4) diff --git a/ecc/bw6-761/twistededwards/point_test.go b/ecc/bw6-761/twistededwards/point_test.go index 87cdc3bbd7..1c47bfc2e1 100644 --- a/ecc/bw6-761/twistededwards/point_test.go +++ b/ecc/bw6-761/twistededwards/point_test.go @@ -951,7 +951,7 @@ func TestIsInSubGroup(t *testing.T) { var t2 PointAffine t2.Y.SetOne().Neg(&t2.Y) - if !testRejectTorsionCoset(&p, &t2) { + if !testRejectTorsionCoset(&p, &t2) { //nolint: staticcheck, we code generate and in some paths we don't return early return false } initOnce.Do(initCurveParams) @@ -963,7 +963,7 @@ func TestIsInSubGroup(t *testing.T) { var t4 PointAffine t4.Y.SetZero() t4.X.Inverse(&sqrtA) - if !testRejectTorsionCoset(&p, &t4) { + if !testRejectTorsionCoset(&p, &t4) { //nolint: staticcheck, we code generate and in some paths we don't return early return false } t8, ok := testTorsion8Point(&t4) diff --git a/internal/generator/edwards/template/tests/point.go.tmpl b/internal/generator/edwards/template/tests/point.go.tmpl index 4a0ef12d54..d79b242b71 100644 --- a/internal/generator/edwards/template/tests/point.go.tmpl +++ b/internal/generator/edwards/template/tests/point.go.tmpl @@ -992,7 +992,7 @@ func TestIsInSubGroup(t *testing.T) { var t2 PointAffine t2.Y.SetOne().Neg(&t2.Y) - if !testRejectTorsionCoset(&p, &t2) { + if !testRejectTorsionCoset(&p, &t2) { //nolint: staticcheck, we code generate and in some paths we don't return early return false } @@ -1006,7 +1006,7 @@ func TestIsInSubGroup(t *testing.T) { var t4 PointAffine t4.Y.SetZero() t4.X.Inverse(&sqrtA) - if !testRejectTorsionCoset(&p, &t4) { + if !testRejectTorsionCoset(&p, &t4) { //nolint: staticcheck, we code generate and in some paths we don't return early return false } From 8833d89ee171455be277aa8014d173d39dabd907 Mon Sep 17 00:00:00 2001 From: Youssef El Housni Date: Thu, 7 May 2026 13:57:36 -0400 Subject: [PATCH 6/8] refactor: apply Ivo suggestions --- .gitignore | 2 ++ addchain/1aaaaaab | Bin 221 -> 0 bytes addchain/1c71c71c55555555 | Bin 427 -> 0 bytes ...d939f24f531918901d9cc89c6c833a18bfa0180000 | Bin 2294 -> 0 bytes ...45f741290002e16ba88600000010a1180000000000 | Bin 3461 -> 0 bytes addchain/38e38e38aaaaaaab | Bin 435 -> 0 bytes addchain/3c000000 | Bin 206 -> 0 bytes addchain/3f | Bin 90 -> 0 bytes addchain/3f800000 | Bin 212 -> 0 bytes ...47970dec00566a9dbfb40000004284600000000000 | Bin 2232 -> 0 bytes addchain/54aaaaab | Bin 234 -> 0 bytes ...b6d0302b0ba5067d090f372e12287c3eb27e000000 | Bin 2274 -> 0 bytes addchain/7 | Bin 68 -> 0 bytes addchain/7fffffff | Bin 232 -> 0 bytes addchain/7fffffff80000000 | Bin 393 -> 0 bytes ...fe51b079a9239a3cf232d7e1cf5e00000000000000 | Bin 2254 -> 0 bytes ...03544f435c0843dcbb4a57bca04dfd005fe8060000 | Bin 2924 -> 0 bytes addchain/d555555 | Bin 214 -> 0 bytes ...0101343b00aa77b4805fffcb7fdfffffffe0000000 | Bin 2284 -> 0 bytes ecc/bls12-377/twistededwards/subgroup.go | 11 ++++++++ ecc/bls12-381/twistededwards/subgroup.go | 11 ++++++++ ecc/bls24-315/twistededwards/subgroup.go | 11 ++++++++ ecc/bls24-317/twistededwards/subgroup.go | 11 ++++++++ ecc/bn254/twistededwards/subgroup.go | 11 ++++++++ ecc/bw6-633/twistededwards/subgroup.go | 11 ++++++++ ecc/bw6-761/twistededwards/subgroup.go | 11 ++++++++ internal/generator/config/bls12-381.go | 3 +++ internal/generator/config/curve.go | 25 ++++++++++++++++++ internal/generator/edwards/generate.go | 3 ++- .../generator/edwards/template/curve.go.tmpl | 14 +++++----- .../generator/edwards/template/point.go.tmpl | 2 +- .../edwards/template/subgroup.go.tmpl | 19 ++++++++++--- .../edwards/template/tests/point.go.tmpl | 10 +++---- .../generator/field/config/field_config.go | 6 ++++- internal/generator/field/config/field_test.go | 10 ++++++- 35 files changed, 151 insertions(+), 20 deletions(-) delete mode 100644 addchain/1aaaaaab delete mode 100644 addchain/1c71c71c55555555 delete mode 100644 addchain/32dbd584953b42564bf8fd939f24f531918901d9cc89c6c833a18bfa0180000 delete mode 100644 addchain/35c748c2f8a21d58c760b80d94292763445b3e601ea271e3de6c45f741290002e16ba88600000010a1180000000000 delete mode 100644 addchain/38e38e38aaaaaaab delete mode 100644 addchain/3c000000 delete mode 100644 addchain/3f delete mode 100644 addchain/3f800000 delete mode 100644 addchain/4aad957a68b2955982d1347970dec00566a9dbfb40000004284600000000000 delete mode 100644 addchain/54aaaaab delete mode 100644 addchain/60c89ce5c263405370a08b6d0302b0ba5067d090f372e12287c3eb27e000000 delete mode 100644 addchain/7 delete mode 100644 addchain/7fffffff delete mode 100644 addchain/7fffffff80000000 delete mode 100644 addchain/887f22fd4d1b5f85a1612fe51b079a9239a3cf232d7e1cf5e00000000000000 delete mode 100644 addchain/98474056b0daca1a7ee9317d2f8bd5fbd83a03544f435c0843dcbb4a57bca04dfd005fe8060000 delete mode 100644 addchain/d555555 delete mode 100644 addchain/e7db4ea6533afa906673b0101343b00aa77b4805fffcb7fdfffffffe0000000 diff --git a/.gitignore b/.gitignore index 4d9d603f74..322e683827 100644 --- a/.gitignore +++ b/.gitignore @@ -32,6 +32,8 @@ internal/tests/integration/ field/internal/dev.go field/internal/dev/** field/generator/addchain/** +internal/generator/field/addchain/ +/addchain/ .vscode diff --git a/addchain/1aaaaaab b/addchain/1aaaaaab deleted file mode 100644 index ab298d417ede2e290f2d03ed6e0258ac58c87daa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 221 zcmWlR%L)Nu07lOl6Otrp5|SoKk|arzWXFbAu(A?)0hg!omSg_S*LP2{Po$;u^L~9^ zZf0N1-q3j!G&((kFfSa8(PNH~{qj~y6k#0f*dmrK2UfwVRjgUVx^-;Wz@|-1Ot57O z+qOg6#h$$|>tkvf9PJh0bv9`2l*d)$q1U!|j$9q?Su?E}+r$*!PgSo-0~v{kL|k;nL6yq0{z zkKfY1@Npml1VoUa2obU$VG$u>=}<(8iWo6l9b4~2#EDxvwe!wwm9T4)B1KA^b1u@P zMTU&Xk`*~}B2Qjia3Km5M3JH>Q4(d!qC!PfF&EdUi8^)Bpdp$xMUrdLq9xk2MTd^) z(iJ^=qEBB87>FT5F=8ZcxfNr^V!}jBnTi=RF=s9u9FgErJo79TEX0zfSg{go);8h4 dT;0uo-do(QG2ac0d>9z{G%)gIU;}c$^$T&DL`(nx diff --git a/addchain/32dbd584953b42564bf8fd939f24f531918901d9cc89c6c833a18bfa0180000 b/addchain/32dbd584953b42564bf8fd939f24f531918901d9cc89c6c833a18bfa0180000 deleted file mode 100644 index d21a756edd01eaf8a10a21cb3959092be9d39632..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2294 zcmXAqab#9|9LB%TxwAVnGcz-5W@ct)W@ct)W@fTGvpX|0GqaoQ&g|~aD>F0Qnn{u* zNs=Tj_31xKHt6PkMsWC^E<1|_9xQsqq%?o&i(a| zvW-x-FJi}kze&lT%M9`bf2bg&A+Hf>(Uvbu)f`C@NkJrqkragrRLrF%p+c3ilrffL z6JJTQAk?Itp+OCXZ+<8=tl`jzMna<+4V7vvG_LW`geF3hnhZ^8Dm1O> z(2Qn6vziU<(yma6c8BIP7n;|6Xh931MJ$=1D&u)0Q>9}q=uG^05j^o;L zTz4JUJ;!z53AHMF;NhX;dgQnsJFX{=>#5^<=D40at{0B$r4wpa_R7O+$Mwc>y>(pg z9M^lt^}z{MD*Nc+ljHjAxV|{9ua4`R_i(B!%vS-q2FP_lZUAx4>=fZPXuya!AV0eJ+-V?dq& z@)VF~fIJ7}1t2d0c?HO8i2Tuc!~7PIcYwTy$e-sA%pU>y1juJVz5wzSkZ*u|2jmAJ zKLPm#+fQ=pImyG408#)*As|J76a!KMNGb4+O_MU_azHA;TbfiddGC`dq#6+axJeCC z3rHOx^?)=0(g;WsAkDzP{xoS}<_21kHbB||=>Vh?kS;*F0qFsx7mz+c`T-dLWG5hl RfD8dL49Ex|qkxP-{0}Hn##jIV diff --git a/addchain/35c748c2f8a21d58c760b80d94292763445b3e601ea271e3de6c45f741290002e16ba88600000010a1180000000000 b/addchain/35c748c2f8a21d58c760b80d94292763445b3e601ea271e3de6c45f741290002e16ba88600000010a1180000000000 deleted file mode 100644 index b701f7bef9834b7c19632ef018d4a156c2fa6e2a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3461 zcmXBV0c6$v8o=@2^WW?y-6Wap%}gelnIuVOW-{H(-brSXbdzqrM5*uPeiH)(b#HQF(VsmUR zu_d;Y*cw|)Oo?qJCS$V1_SjxxN9-uEGj^70SBc%RyTqQ@7Qrt}{8g&gSGgmy_#! zj^CwzArBXGa$U;FbvY;3m7H8xb8=nF$#p#^*NvRU^SPOaTREkw-_E>~lk09yu6sGT z?&suskdy0SPOe8exgO`_dXkgtX^z*s{wxpAb8@}N$@MZP*Q=aduXA#}$;tILC)c~2 zT<>#oeaOl6F(=ojoD#F6{y7g{a&mpm$@MKK*Y})UKXSZ*^`Ck8m6PjtPOe%`iCQ$c zRESnY8-Bdz9;oFfIf-eA>4+JKnTT1G#zWhkXCpcga}b?~F2r0!H{P3?d#9FnPZB+d zUPK>a0dA3+JE|6o5Q`B@X#QeLo%<03h(W{u^h32=07;%Jc<}YtVFCrj3XxS zX4c%DwOE5#i&%$PkJy0Nh}cAFyri3*w;;A6wjm~Qv(((pwY;B`*ooMM*p1kO*o)YQ z*pE1XIEXleI814LNRBukMI1vMN1UMf)|_-cg*c5kgE)&ghd7V8fVfC$d>Ah|Uq)O( zTt!?%T&MYV-f+H&xP`clZ}wW;alVVVhq#Y;fOv>_gm_HzRe9q46!8r49PtA2lIG96 za(<0?gLsR0hj@?pfcQxBGxy2)GvW*4E8-jCJK_i8C*l{)7worl<4;D_;8G!45p9Sm zG(Nf2ROe}k>4+JKnTT14b{by~)okYu#2iE?q6;w>(T$jgn2+e8@#R(ZI`<(KAQmDP zAr{m8nI+Ck5&eh(#2{h_u?#VcSdLhM7(t98#t_gm{d2f_RE}hIo#6fq02{g?NpZ@r~14#5=@$#0SJj#3#gOn(x{d z=dXxwi0_CWh@XgGh~J1B87&QsFQ1l5x027brOjyyVk%-9B0r}s)5Q$LOvEfiJ7PAX z12G5DiRePiMRX(PA?71`5WR>#!~(=Z#3ICE#1h0(L_cBxF^CvKEJF+nlH?EedS2>uPxsf; zy-&YF`kZK6wQ+ge*grRIV)_LAk1d+4*RzW;uwo9a#0fv%$5eD9Oigj(1gB1M<_zb~ap3}&E^*}w*RFBn2Dff;=MFP7%*}D{o?Fvxar+|J=Z)O^l7PWeeN3 zv1=E5_AoKQfdd>m#E~N$JI09VY@OR4f+~U$gcZo1=UBA@X1UhC2TfSs?tzaWuY=I8CCFDC7-Pd z<&=x0I#i*WP?cO+)p7JCtARti z+IY?w&spO+XSnU@c^@tq&qd?8WIUIR=Zf)MHJ)q6bKQ7u7|%@;YEpX3hug+;$9V1< z&pqS0Z#)l-=b`aDGM>jK)S~o>4^NHfnejX~o)^aR(s*7O&uim(V?1w-=bb5julGKD zFrJUb^T~KV8_yTx`D#4hjOV)vwJZJM!%yS+Wjw!)r(i+_73Gp3kwKyaL(QHn=Taof zkSIr@0*Oi_s*uPbQH`NmPYq|HmZ(Fb9*G7d8j)y1f>+Z_v>?%nL>m(ANNho(1Bp%~ zx{&Bbq6hhXD)62w_+4j-ZAkPX(T~Ic5`#z#Au)`^2oj?h#g{q8c^ruyNK7CxiNq8V z(@4x9F^j|;67v|vpL!?f1tb=cSVAI?#4-{qNUS2UhWx22@J{Dm?&0BmNUS5Vfl>T@ zIl%cK5{HmDjKmQnjv{dkiQ`C|K;k44r;s>}#2F;cB5@9h^GIAk;vy24khqM*6(p`A zaSe&<{4~hFoJV4?h5|5C0jQlSs=n3biNIXO0ITA0Bc!|U- zBwi!&28p*wyu&EIJ>PTwfW${6J|XcLi7!ZeMdBM0-;wx%#7`uCA@LiD;)f$C$|XS} zgG31uStLr4C_|zgi3%htk*Go?%nL>m(A WNNho(1Bp%~x{&Bbq6djyjQ;_h^t?I% diff --git a/addchain/54aaaaab b/addchain/54aaaaab deleted file mode 100644 index 9a8419e287a4d5b0f3056f6dffb8fe0081f352fe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 234 zcmWlP(MkeQ00n2RVj&@m$RaAsA|{K7h=_!Uh=^1#`U^h!6oo%v^-q1@cK2oA%$cu!gz*NN7}};SVqt8rOJeLKC5!a-m60hAOlr zG^MFXwuYuP9h%WhXjZeKIn9OUH6PlhZK3Vj9$L@>H?bqMsKrQjg_g7w$}1mQ)^cdK zc8B(8PiRFep;fJhDz%r@&DONAR$S|K71sUB1CHyU<2vNH4m++Rj_au7I_88*RXFb9 zgyTBtxK25)(~j$m<2vhb>B2b==N;Dtheaz~^l-^>Z8)yWj_Zo!y6U*DIj-wYcIg`) zZaS`8j_bDLy5qR+I<9+8B!&Cd2afBZ<9g({9y_ilj_ax8dgkzb6rOu{;kaHpu2+uh zwc~o@WFPFUhj)(az2o}eWHQbwTwfj6H^=qeas6;yKb>rKetAfpP^t_L z2_Pkalmb!)NI4)CfK&pvl(HdG?*@Zx0;C4GY|8dXy+I684@d(bjes-((hNuoAg#bU zrfi|qo5&y?fOJCfmb#d`0qFsx7mz+c`l0wY1I&Yf3;{9>$Os^#fQ$h$4#kf;!JGqR z5|Ax`OaZbLkZC|>AhHFVWu60M9wJHEtf{xFK^6en0mvdCy8u}NBoD|ku+>vGbm}c_ zkQG2y0oe=4en8d$SqJ0*gsNNznGXSS7?2}?90lYUAjg46KGg~4lYpFp;)0%LJ_E>E zK+XYj9*_%wT!iA2a*25ZSiZ|lR{*&R$TdK&19Ah9n}FN`{S^L}Uk0mx54egTsGSdxrv_4#L-CMAHB0#XM4K9X{#3PAi6B$Y@NAk~0u0;C3z zTFCA!sbj7O&e_1!2uKqk&49E3(h5i$Anky30MZFa7a-k$^Z?QeNFN~mfD8aK2*?m1 U!+?wcG788TAme~c0Fs0FAL8)5N&o-= diff --git a/addchain/7 b/addchain/7 deleted file mode 100644 index c1410c6d13353d0351fa753eb3fe120b9d7c4f57..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 68 zcmWgp-^j$s$R1FXpI(%h%lN;Ef$@I>1A}xuGb1CDe*uWY2vp$7$il$L=mjJh7zBWd QSQwa?7#LZAd?q#q072&rs{jB1 diff --git a/addchain/7fffffff b/addchain/7fffffff deleted file mode 100644 index 2702c2bd601e9bdec1d5ecace2b67f582b0c5adf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 232 zcmWlQO=`kW00w7XLn|U8Qi50!2~k8uL_|bHL_};idIeWq6-zGApDXo%>C0wdKITiy zpP*0I;{IOTJ}iH+{DzmW2Mw3cN{qp)3HlZZACJb1vPM?87LXV3ft1hW{5 diff --git a/addchain/7fffffff80000000 b/addchain/7fffffff80000000 deleted file mode 100644 index 3f6891cde4118c5c70424386a705be833d3be08c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 393 zcmXAl{YQfV6h_ZkS((fvGizoh$z&$UWRf+h%$k~+B$cVms(DQ^Ss(hld)r&TT+e+R zmwVFTXG|B`!Sj7^^Jw^m;Rmd~&uQ#*6fMqxW9QM6*@Pd@XV?L;7|ut1+<250F<}Ci zT*9PDOqq(hWn6Iu)21U94HdJ@;_meXLu@hK=anAs%_e?12+(+QgPEY}>{&&#+?$yLPc>4==pH zOE2-tE4=m^Z@tC7eZ2DyAAG=p0~|WUC!cWS2m=EgJH{7Z@YPqGIKemHaOyNN{O2|N K`uF{9_{}eE3pU~a diff --git a/addchain/887f22fd4d1b5f85a1612fe51b079a9239a3cf232d7e1cf5e00000000000000 b/addchain/887f22fd4d1b5f85a1612fe51b079a9239a3cf232d7e1cf5e00000000000000 deleted file mode 100644 index a7f5393649459ac9e038062a83aa0da27a3a4e7a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2254 zcmXAp0c4eX9EN}IcW3vQnVDl|cP2A4Gcz+YGcz-@JF`2JOlEdxb|<^LGcz-@+nppy zl4O!3Ns=TsSCN+hc)f{S3OQ=QPUqSG}P=^@aM?9~#g=Xi$Tp3JryZH5?kzNN7}}p)rkxc4}v6mv)85 zHO`0F9h%TYXi}4*DNTi@H65DKOlVfKp*hWksr(79#f7nkiGNp-f?|!Tpu0RC&%^KVXLw)9= z3m~n4v;oo%NC&VPDQ7HI7a-k$^Z?QeNFN~mfD8aK2*?mb;bRXoj{q_X$QZCcDd#fv z$u!6~AiDvX0Av!7DL|%S`(Dm4&jKd{eT<*067bM+od|k zd>)VsfLsLR5+IiWxdO;lK&}CD9grKaz0)_DZvk=}kUN0f1>_z?;UL^+egMcrKpp|| z7?3Bhy;)D0p8@h5kQacw1mqPUuK{@j$Xh_(0rDP@4}g3G*RS3tf2@*R*L zfcylc@MB2|uq1#K0a6S|4v-Q+N&zVYq#Te6K=Oc80#XG?H6VVZk{YBIkR5>30pbTH tsYe4=m{_ihR^5-~*{04t0FQhg*1qK&-pm-@w(vgy6Ew`!HW%k;m(?$LonFRI2o;k7pjQEsxi>$LqPr>xIYbrN`@) zCsd^LwU0L*ueTnrcOI|z9mVUDG<{jW zm;-SFk$p|(xfehzf>;8v4B{k+Q;6&vXN7we#Ay&`K&*jS2XPj}IS}Wu^HsXQeG$YZ z5SKw*0dWoC+^Q6zJT}&;v0zX;Qz3k zesKQ;k^OQc86F9UJP`RH3Xr{El0xoXAa;W&0^z?YDJDull!7Qj@be_u!(9%7-`Pu4 zfY=A362yKG2S6M|_VXh-#9amAFo+`{szKC%s73GtE2-nI2hjkc5kwP+W)Lmd`9NB^ z+d#B~=m60Pq6*SI_?jaDvAdZ4K24V!nD2Oo-;|PB8CKKF~ zAf^yWE}7<<0Wk|=4#Wu%^B@*LEP_}9u?*rQc=xBcRzR$RI1Sq1*Z{E!;x>po$bP^ice(F@xDVn1h=(8^ hfp`q!35cg4o`Ki`u?^xmh!-GUf_MeuHHbHe{{b9Zp^pFn diff --git a/addchain/d555555 b/addchain/d555555 deleted file mode 100644 index 47ff9dfbee60e19c927ac66513e633f5df60b9ea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 214 zcmWlR%?d$b00n10LXsrigoGqXk|as8Wy332S&6)WpEvQO*Znr9&YbBa=_hFM{JdYE zmz(Jq(>JtVISr>rEM~&NJbKI$(qCrvBMyWN7c5}O5|%ATT*0bUtXadlb!^zc!~~l* z#cV=dGkC~ZCW@ct)c4u~HW+pScGrKdZJIBn->~=Fr zk|arzBuSDalO#!!BuSDaNs=T|eW; z-xtd7jri@~U!>&EWrqBQKU5OZkk5!**|y)7)9;Zak@)pQrJ*vFag;|=5h_t7FIRD- zLgiSc(!8N2RK<~~E>x}BP=y+pjm#!~+Z-xYCX`l7D5X|r8&_#(+EVHWb#Qd5Gt{N7 zP`A26J?aVdsyEc9zEHpVL+u&}4Qeoa`$M5&4TnZF5*pQLXiQ_FagB#2G!dHAWT-{E zLQ|RwO=~(dqnXgGW-|}nw9oGTJb$92tdZ9Ac6<*$3(a9lSX*Dc3& z+i~4-Tz4JUJ;!z5aXoNCjmkgtc;vVqJFX{=>#5^<=D40at{0B$r4y=E{*}jT$Mwc> zy>(pg9M^lt^}%s{bX=dDNb;YpUmVw0$Mwx|eRo_x9M@0Bm2*Nl72rq!DFLJukTO8Z z0jYpcy{nR41xN~zYCzI})BsWoNF5+trygklq!D-|IsSce{&)R1f&y?Een{kUogQ-Sx8v02u^i2#{ewMgSQFWDJmTKqdg0gectRF7^~4 z(}2tXG7HEYAoGAM0I~?7Cf5>s4_wR@9sVO10Wv(`2@&kK)wL-6_9U$e23!Yez1Q6QuwhX1vnBw zN&qPZqzsU9C|r&&-ds`%NEPr^oJ&&dYCzI})BsWoNF5;cfHVNo2uKqk&46S8X#u1a qkTyWt0qFo_2Ov8E=>((;kZwSF0O Date: Thu, 7 May 2026 14:03:51 -0400 Subject: [PATCH 7/8] refactor: remove unused variables --- ecc/bls12-381/twistededwards/subgroup.go | 3 +-- ecc/bls24-315/twistededwards/subgroup.go | 3 +-- ecc/bls24-317/twistededwards/subgroup.go | 3 +-- ecc/bn254/twistededwards/subgroup.go | 3 +-- ecc/bw6-633/twistededwards/subgroup.go | 3 +-- ecc/bw6-761/twistededwards/subgroup.go | 3 +-- internal/generator/edwards/template/subgroup.go.tmpl | 3 +-- 7 files changed, 7 insertions(+), 14 deletions(-) diff --git a/ecc/bls12-381/twistededwards/subgroup.go b/ecc/bls12-381/twistededwards/subgroup.go index 6b66ea9bdc..3a9fe97927 100644 --- a/ecc/bls12-381/twistededwards/subgroup.go +++ b/ecc/bls12-381/twistededwards/subgroup.go @@ -71,9 +71,8 @@ func initCofactorSubgroupParams() { initCofactorEightTorsion(&t4) } func initCofactorEightTorsion(t4 *PointAffine) { - var one, two, aInv, discr, discrSqrt, x2, y2, t fr.Element + var one, aInv, discr, discrSqrt, x2, y2, t fr.Element one.SetOne() - two.SetUint64(2) aInv.Inverse(&curveParams.A) discr.Set(&curveParams.D).Neg(&discr).Mul(&discr, &aInv).Add(&discr, &one) if discrSqrt.Sqrt(&discr) == nil { diff --git a/ecc/bls24-315/twistededwards/subgroup.go b/ecc/bls24-315/twistededwards/subgroup.go index 67803165a3..b057616c79 100644 --- a/ecc/bls24-315/twistededwards/subgroup.go +++ b/ecc/bls24-315/twistededwards/subgroup.go @@ -71,9 +71,8 @@ func initCofactorSubgroupParams() { initCofactorEightTorsion(&t4) } func initCofactorEightTorsion(t4 *PointAffine) { - var one, two, aInv, discr, discrSqrt, x2, y2, t fr.Element + var one, aInv, discr, discrSqrt, x2, y2, t fr.Element one.SetOne() - two.SetUint64(2) aInv.Inverse(&curveParams.A) discr.Set(&curveParams.D).Neg(&discr).Mul(&discr, &aInv).Add(&discr, &one) if discrSqrt.Sqrt(&discr) == nil { diff --git a/ecc/bls24-317/twistededwards/subgroup.go b/ecc/bls24-317/twistededwards/subgroup.go index 667c3153ec..17e8b44a26 100644 --- a/ecc/bls24-317/twistededwards/subgroup.go +++ b/ecc/bls24-317/twistededwards/subgroup.go @@ -71,9 +71,8 @@ func initCofactorSubgroupParams() { initCofactorEightTorsion(&t4) } func initCofactorEightTorsion(t4 *PointAffine) { - var one, two, aInv, discr, discrSqrt, x2, y2, t fr.Element + var one, aInv, discr, discrSqrt, x2, y2, t fr.Element one.SetOne() - two.SetUint64(2) aInv.Inverse(&curveParams.A) discr.Set(&curveParams.D).Neg(&discr).Mul(&discr, &aInv).Add(&discr, &one) if discrSqrt.Sqrt(&discr) == nil { diff --git a/ecc/bn254/twistededwards/subgroup.go b/ecc/bn254/twistededwards/subgroup.go index b4c7ad0215..f7fe449c86 100644 --- a/ecc/bn254/twistededwards/subgroup.go +++ b/ecc/bn254/twistededwards/subgroup.go @@ -71,9 +71,8 @@ func initCofactorSubgroupParams() { initCofactorEightTorsion(&t4) } func initCofactorEightTorsion(t4 *PointAffine) { - var one, two, aInv, discr, discrSqrt, x2, y2, t fr.Element + var one, aInv, discr, discrSqrt, x2, y2, t fr.Element one.SetOne() - two.SetUint64(2) aInv.Inverse(&curveParams.A) discr.Set(&curveParams.D).Neg(&discr).Mul(&discr, &aInv).Add(&discr, &one) if discrSqrt.Sqrt(&discr) == nil { diff --git a/ecc/bw6-633/twistededwards/subgroup.go b/ecc/bw6-633/twistededwards/subgroup.go index 3c51ff8c89..825e7fc320 100644 --- a/ecc/bw6-633/twistededwards/subgroup.go +++ b/ecc/bw6-633/twistededwards/subgroup.go @@ -71,9 +71,8 @@ func initCofactorSubgroupParams() { initCofactorEightTorsion(&t4) } func initCofactorEightTorsion(t4 *PointAffine) { - var one, two, aInv, discr, discrSqrt, x2, y2, t fr.Element + var one, aInv, discr, discrSqrt, x2, y2, t fr.Element one.SetOne() - two.SetUint64(2) aInv.Inverse(&curveParams.A) discr.Set(&curveParams.D).Neg(&discr).Mul(&discr, &aInv).Add(&discr, &one) if discrSqrt.Sqrt(&discr) == nil { diff --git a/ecc/bw6-761/twistededwards/subgroup.go b/ecc/bw6-761/twistededwards/subgroup.go index d3d24e7ddb..dfb250c4da 100644 --- a/ecc/bw6-761/twistededwards/subgroup.go +++ b/ecc/bw6-761/twistededwards/subgroup.go @@ -71,9 +71,8 @@ func initCofactorSubgroupParams() { initCofactorEightTorsion(&t4) } func initCofactorEightTorsion(t4 *PointAffine) { - var one, two, aInv, discr, discrSqrt, x2, y2, t fr.Element + var one, aInv, discr, discrSqrt, x2, y2, t fr.Element one.SetOne() - two.SetUint64(2) aInv.Inverse(&curveParams.A) discr.Set(&curveParams.D).Neg(&discr).Mul(&discr, &aInv).Add(&discr, &one) if discrSqrt.Sqrt(&discr) == nil { diff --git a/internal/generator/edwards/template/subgroup.go.tmpl b/internal/generator/edwards/template/subgroup.go.tmpl index bc8a0ed4ea..96174aed22 100644 --- a/internal/generator/edwards/template/subgroup.go.tmpl +++ b/internal/generator/edwards/template/subgroup.go.tmpl @@ -73,9 +73,8 @@ func initCofactorSubgroupParams() { {{- if .HasOcticSubgroupCheck}} func initCofactorEightTorsion(t4 *PointAffine) { - var one, two, aInv, discr, discrSqrt, x2, y2, t fr.Element + var one, aInv, discr, discrSqrt, x2, y2, t fr.Element one.SetOne() - two.SetUint64(2) aInv.Inverse(&curveParams.A) discr.Set(&curveParams.D).Neg(&discr).Mul(&discr, &aInv).Add(&discr, &one) if discrSqrt.Sqrt(&discr) == nil { From 0b7114b2c81ff3437bc7f34f5c1cfe97c23aa858 Mon Sep 17 00:00:00 2001 From: Youssef El Housni Date: Thu, 7 May 2026 14:35:36 -0400 Subject: [PATCH 8/8] refactor: apply copilot/cursor suggestions --- ecc/bls12-381/bandersnatch/subgroup.go | 6 ------ internal/generator/config/curve.go | 21 ++++++++++++++------- internal/generator/edwards/generate.go | 4 +++- 3 files changed, 17 insertions(+), 14 deletions(-) delete mode 100644 ecc/bls12-381/bandersnatch/subgroup.go diff --git a/ecc/bls12-381/bandersnatch/subgroup.go b/ecc/bls12-381/bandersnatch/subgroup.go deleted file mode 100644 index 744fe3f835..0000000000 --- a/ecc/bls12-381/bandersnatch/subgroup.go +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright 2020-2026 Consensys Software Inc. -// Licensed under the Apache License, Version 2.0. See the LICENSE file for details. - -// Code generated by consensys/gnark-crypto DO NOT EDIT - -package bandersnatch diff --git a/internal/generator/config/curve.go b/internal/generator/config/curve.go index e73bb2326c..5534337b88 100644 --- a/internal/generator/config/curve.go +++ b/internal/generator/config/curve.go @@ -295,17 +295,24 @@ func addTwistedEdwardCurve(c *TwistedEdwardsCurve) { ad.Mul(&a, &d).Mod(&ad, &modulus) c.Split2Torsion = legendreSymbol(&ad, &modulus) == 1 - var exp big.Int - exp.Sub(&modulus, big.NewInt(1)) switch c.Cofactor { - case "4": - if !c.Split2Torsion { + case "4", "8": + if !c.HasSubgroupCheck() { + panic("unsupported twisted Edwards subgroup check configuration for " + c.Name + "/" + c.Package) + } + } + + if c.HasNonSplitSubgroupCheck() { + var exp big.Int + exp.Sub(&modulus, big.NewInt(1)) + switch c.Cofactor { + case "4": exp.Rsh(&exp, 2) c.QuarticExponentData = addchain.GetAddChain(&exp) + case "8": + exp.Rsh(&exp, 3) + c.OcticExponentData = addchain.GetAddChain(&exp) } - case "8": - exp.Rsh(&exp, 3) - c.OcticExponentData = addchain.GetAddChain(&exp) } TwistedEdwardsCurves = append(TwistedEdwardsCurves, *c) diff --git a/internal/generator/edwards/generate.go b/internal/generator/edwards/generate.go index b0c0696891..0c26552189 100644 --- a/internal/generator/edwards/generate.go +++ b/internal/generator/edwards/generate.go @@ -14,11 +14,13 @@ import ( func Generate(conf config.TwistedEdwardsCurve, baseDir string, gen *common.Generator) error { entries := []bavard.Entry{ {File: filepath.Join(baseDir, "point.go"), Templates: []string{"point.go.tmpl"}}, - {File: filepath.Join(baseDir, "subgroup.go"), Templates: []string{"subgroup.go.tmpl"}}, {File: filepath.Join(baseDir, "point_test.go"), Templates: []string{"tests/point.go.tmpl"}}, {File: filepath.Join(baseDir, "doc.go"), Templates: []string{"doc.go.tmpl"}}, {File: filepath.Join(baseDir, "curve.go"), Templates: []string{"curve.go.tmpl"}}, } + if conf.HasNonSplitSubgroupCheck() { + entries = append(entries, bavard.Entry{File: filepath.Join(baseDir, "subgroup.go"), Templates: []string{"subgroup.go.tmpl"}}) + } edwardsGen := common.NewDefaultGenerator(template.FS) funcs := make(stdtemplate.FuncMap)