@@ -2,7 +2,6 @@ package _weierstrass
22
33import " core:math/bits"
44import " core:mem"
5- import " core:slice"
65
76pt_scalar_mul :: proc " contextless" (
87 p, a: ^$T ,
@@ -11,15 +10,15 @@ pt_scalar_mul :: proc "contextless" (
1110) {
1211 when T == Point_p256r1 && S == Scalar_p256r1 {
1312 p_tbl: Multiply_Table_p256r1 = ---
14- q, tmp: Point_p256r1
13+ q, tmp: Point_p256r1 = --- , ---
1514 SC_SZ :: SC_SIZE_P256R1
1615 } else {
1716 #panic (" weierstrass: invalid curve" )
1817 }
1918
2019 mul_tbl_set (&p_tbl, a, unsafe_is_vartime)
2120
22- b: [SC_SZ]byte
21+ b: [SC_SZ]byte = ---
2322 sc_bytes (b[:], sc)
2423
2524 pt_identity (&q)
@@ -32,16 +31,13 @@ pt_scalar_mul :: proc "contextless" (
3231 pt_double (&q, &q)
3332 pt_double (&q, &q)
3433 }
35-
36- mul_tbl_lookup (&tmp, &p_tbl, u64 (hi), unsafe_is_vartime)
37- pt_add (&q, &q, &tmp)
34+ mul_tbl_lookup_add (&q, &tmp, &p_tbl, u64 (hi), unsafe_is_vartime)
3835
3936 pt_double (&q, &q)
4037 pt_double (&q, &q)
4138 pt_double (&q, &q)
4239 pt_double (&q, &q)
43- mul_tbl_lookup (&tmp, &p_tbl, u64 (lo), unsafe_is_vartime)
44- pt_add (&q, &q, &tmp)
40+ mul_tbl_lookup_add (&q, &tmp, &p_tbl, u64 (lo), unsafe_is_vartime)
4541 }
4642
4743 pt_set (p, &q)
@@ -53,6 +49,50 @@ pt_scalar_mul :: proc "contextless" (
5349 }
5450}
5551
52+ pt_scalar_mul_generator :: proc " contextless" (
53+ p: ^$T ,
54+ sc: ^$S ,
55+ unsafe_is_vartime: bool = false ,
56+ ) {
57+ when T == Point_p256r1 && S == Scalar_p256r1 {
58+ p_tbl := &Gen_Multiply_Table_p256r1
59+ tmp: Point_p256r1 = ---
60+ SC_SZ :: SC_SIZE_P256R1
61+ } else {
62+ #panic (" weierstrass: invalid curve" )
63+ }
64+
65+ b: [SC_SZ]byte
66+ sc_bytes (b[:], sc)
67+
68+ // Note: The point doublings can be eliminated entirely
69+ // at the cost of having 64 Gen_Multiply_Table's, but
70+ // that's a considerable amount of data.
71+ pt_identity (p)
72+ for limb_byte, i in b {
73+ hi, lo := (limb_byte >> 4 ) & 0x0f , limb_byte & 0x0f
74+
75+ if i != 0 {
76+ pt_double (p, p)
77+ pt_double (p, p)
78+ pt_double (p, p)
79+ pt_double (p, p)
80+ }
81+ mul_affine_tbl_lookup_add (p, &tmp, p_tbl, u64 (hi), unsafe_is_vartime)
82+
83+ pt_double (p, p)
84+ pt_double (p, p)
85+ pt_double (p, p)
86+ pt_double (p, p)
87+ mul_affine_tbl_lookup_add (p, &tmp, p_tbl, u64 (lo), unsafe_is_vartime)
88+ }
89+
90+ if !unsafe_is_vartime {
91+ mem.zero_explicit (&b, size_of (b))
92+ pt_clear (&tmp)
93+ }
94+ }
95+
5696@ (private = " file" )
5797Multiply_Table_p256r1 :: [15 ]Point_p256r1
5898
@@ -81,26 +121,131 @@ mul_tbl_set :: proc "contextless"(
81121}
82122
83123@ (private = " file" )
84- mul_tbl_lookup :: proc " contextless" (
85- point: ^$T ,
124+ mul_tbl_lookup_add :: proc " contextless" (
125+ point, tmp : ^$T ,
86126 tbl: ^$U ,
87127 idx: u64 ,
88128 unsafe_is_vartime: bool ,
89129 ) {
90130 if unsafe_is_vartime {
91131 switch idx {
92132 case 0 :
93- pt_identity (point)
94133 case :
95- pt_set ( point, &tbl[idx - 1 ])
134+ pt_add (point, point, &tbl[idx - 1 ])
96135 }
97136 return
98137 }
99138
100- pt_identity (point )
139+ pt_identity (tmp )
101140 for i in u64 (1 )..<16 {
102141 _, ctrl := bits.sub_u64 (0 , (i ~ idx), 0 )
103- pt_cond_select (point, point, &tbl[i - 1 ], int (~ctrl) & 1 )
142+ pt_cond_select (tmp, tmp, &tbl[i - 1 ], int (~ctrl) & 1 )
143+ }
144+
145+ pt_add (point, point, tmp)
146+ }
147+
148+ @ (private = " file" )
149+ Affine_Point_p256r1 :: struct {
150+ _x: Field_Element_p256r1,
151+ _y: Field_Element_p256r1,
152+ }
153+
154+ @ (private = " file" )
155+ mul_affine_tbl_lookup_add :: proc " contextless" (
156+ point, tmp: ^$T ,
157+ tbl: ^$U ,
158+ idx: u64 ,
159+ unsafe_is_vartime: bool ,
160+ ) {
161+ if unsafe_is_vartime {
162+ switch idx {
163+ case 0 :
164+ case :
165+ pt_add_mixed (point, point, &tbl[idx - 1 ]._x, &tbl[idx - 1 ]._y)
166+ }
167+ return
104168 }
169+
170+ pt_identity (tmp)
171+ for i in u64 (1 )..<16 {
172+ _, borrow := bits.sub_u64 (0 , (i ~ idx), 0 )
173+ ctrl := int (~borrow & 1 )
174+ fe_cond_select (&tmp._x, &tmp._x, &tbl[i - 1 ]._x, ctrl)
175+ fe_cond_select (&tmp._y, &tmp._y, &tbl[i - 1 ]._y, ctrl)
176+ }
177+
178+ // The mixed addition formula assumes that the addend is not
179+ // the neutral element. Do the addition regardless, and then
180+ // conditionally select the right result.
181+ pt_add_mixed (tmp, point, &tmp._x, &tmp._y)
182+
183+ _, borrow := bits.sub_u64 (0 , idx, 0 )
184+ pt_cond_select (point, point, tmp, int (borrow) & 1 )
105185}
106186
187+ @ (private = " file" )
188+ Gen_Multiply_Table_p256r1 := [15 ]Affine_Point_p256r1 {
189+ {
190+ {8784043285714375740 , 8483257759279461889 , 8789745728267363600 , 1770019616739251654 },
191+ {15992936863339206154 , 10037038012062884956 , 15197544864945402661 , 9615747158586711429 },
192+ },
193+ {
194+ {9583737883674400333 , 12279877754802111101 , 8296198976379850969 , 17778859909846088251 },
195+ {3401986641240187301 , 1525831644595056632 , 1849003687033449918 , 8702493044913179195 },
196+ },
197+ {
198+ {18423170064697770279 , 12693387071620743675 , 7398701556189346968 , 2779682216903406718 },
199+ {12703629940499916779 , 6358598532389273114 , 8683512038509439374 , 15415938252666293255 },
200+ },
201+ {
202+ {8408419572923862476 , 5066733120953500019 , 926242532005776114 , 6301489109130024811 },
203+ {3285079390283344806 , 1685054835664548935 , 7740622190510199342 , 9561507292862134371 },
204+ },
205+ {
206+ {13698695174800826869 , 10442832251048252285 , 10672604962207744524 , 14485711676978308040 },
207+ {16947216143812808464 , 8342189264337602603 , 3837253281927274344 , 8331789856935110934 },
208+ },
209+ {
210+ {4627808394696681034 , 6174000022702321214 , 15351247319787348909 , 1371147458593240691 },
211+ {10651965436787680331 , 2998319090323362997 , 17592419471314886417 , 11874181791118522207 },
212+ },
213+ {
214+ {524165018444839759 , 3157588572894920951 , 17599692088379947784 , 1421537803477597699 },
215+ {2902517390503550285 , 7440776657136679901 , 17263207614729765269 , 16928425260420958311 },
216+ },
217+ {
218+ {2878166099891431311 , 5056053391262430293 , 10345032411278802027 , 13214556496570163981 },
219+ {17698482058276194679 , 2441850938900527637 , 1314061001345252336 , 6263402014353842038 },
220+
221+ },
222+ {
223+ {8487436533858443496 , 12386798851261442113 , 3224748875345095424 , 16166568617729909099 },
224+ {2213369110503306004 , 6246347469485852131 , 3129440554298978074 , 605269941184323483 },
225+ },
226+ {
227+ {3177531230451277512 , 11022989490494865721 , 8321856985295555401 , 14727273563873821327 },
228+ {876865438755954294 , 14139765236890058248 , 6880705719513638354 , 8678887646434118325 },
229+
230+ },
231+ {
232+ {16896703203004244996 , 11377226897030111200 , 2302364246994590389 , 4499255394192625779 },
233+ {1906858144627445384 , 2670515414718439880 , 868537809054295101 , 7535366755622172814 },
234+ },
235+ {
236+ {339769604981749608 , 12384581172556225075 , 2596838235904096350 , 5684069910326796630 },
237+ {913125548148611907 , 1661497269948077623 , 2892028918424825190 , 9220412792897768138 },
238+ },
239+ {
240+ {14754959387565938441 , 1023838193204581133 , 13599978343236540433 , 8323909593307920217 },
241+ {3852032956982813055 , 7526785533690696419 , 8993798556223495105 , 18140648187477079959 },
242+ },
243+ {
244+ {11692087196810962506 , 1328079167955601379 , 1664008958165329504 , 18063501818261063470 },
245+ {2861243404839114859 , 13702578580056324034 , 16781565866279299035 , 1524194541633674171 },
246+ },
247+ {
248+ {8267721299596412251 , 273633183929630283 , 17164190306640434032 , 16332882679719778825 },
249+ {4663567915067622493 , 15521151801790569253 , 7273215397645141911 , 2324445691280731636 },
250+ },
251+ }
0 commit comments