Skip to content

Commit 2f37315

Browse files
committed
fixup! core/crypto: Start work on the NIST curves
1 parent 2a0b9d6 commit 2f37315

File tree

3 files changed

+180
-30
lines changed

3 files changed

+180
-30
lines changed

core/crypto/_weierstrass/p256_test.odin

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,12 +93,13 @@ test_p256_g_y :: proc(t: ^testing.T) {
9393

9494
@(test)
9595
test_p256_scalarmul :: proc(t: ^testing.T) {
96-
p, q, r: Point_p256r1
96+
g, p, q, r: Point_p256r1
9797
sc: Scalar_p256r1
9898
b: [1]byte
9999
tmp: [32]byte
100100

101-
pt_generator(&p)
101+
pt_generator(&g)
102+
pt_identity(&p)
102103
pt_identity(&q)
103104
pt_identity(&r)
104105

@@ -110,13 +111,16 @@ test_p256_scalarmul :: proc(t: ^testing.T) {
110111
s := string(hex.encode(tmp[:], context.temp_allocator))
111112

112113
if i != 0 {
113-
pt_add(&q, &q, &p)
114+
pt_add(&p, &p, &g)
114115
}
115-
pt_scalar_mul(&r, &p, &sc)
116+
pt_scalar_mul(&q, &g, &sc)
117+
pt_scalar_mul_generator(&r, &sc)
118+
pt_rescale(&p, &p)
116119
pt_rescale(&q, &q)
117120
pt_rescale(&r, &r)
118121

119-
testing.expectf(t, pt_equal(&q, &r) == 1, "sc: %s, %v %v", s, q, r)
122+
testing.expectf(t, pt_equal(&p, &q) == 1, "sc: %s, %v %v", s, q, r)
123+
testing.expectf(t, pt_equal(&p, &r) == 1, "sc: %s, %v %v", s, q, r)
120124
}
121125
}
122126

core/crypto/_weierstrass/point.odin

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ pt_add :: proc "contextless" (p, a, b: ^$T) {
255255
}
256256

257257
@(private)
258-
pt_add_mixed :: proc "contextless" (p, a, b: ^$T) {
258+
pt_add_mixed :: proc "contextless" (p, a: ^$T, x2, y2: ^$U) {
259259
// Algorithm 5 from "Complete addition formulas for prime
260260
// order elliptic curves" by Renes, Costello, and Batina.
261261
//
@@ -266,7 +266,7 @@ pt_add_mixed :: proc "contextless" (p, a, b: ^$T) {
266266
// The operation costs are `11M + 2mb + 23a` saving
267267
// `1M + 6a` over `pt_add`.
268268

269-
when T == Point_p256r1 {
269+
when T == Point_p256r1 && U == Field_Element_p256r1 {
270270
t0, t1, t2, t3, t4, b_fe: Field_Element_p256r1
271271
x3, y3, z3: Field_Element_p256r1
272272
defer fe_clear_vec([]^Field_Element_p256r1{&t0, &t1, &t2, &t3, &t4, &x3, &y3, &z3})
@@ -275,7 +275,6 @@ pt_add_mixed :: proc "contextless" (p, a, b: ^$T) {
275275
}
276276

277277
x1, y1, z1 := &a._x, &a._y, &a._z
278-
x2, y2 := &b._x, &b._y
279278

280279
fe_b(&b_fe)
281280

@@ -533,15 +532,17 @@ is_on_curve :: proc "contextless" (x, y: ^$T) -> bool {
533532
@(private)
534533
set_yy_candidate :: proc "contextless" (maybe_yy, x: ^$T) {
535534
// RHS: x^3 + ax + b
536-
a_x, b_fe: T
535+
rhs, tmp: T
537536

538-
fe_square(maybe_yy, x)
539-
fe_mul(maybe_yy, maybe_yy, x)
537+
fe_square(&tmp, x)
538+
fe_mul(&rhs, &tmp, x)
540539

541-
fe_a(&a_x)
542-
fe_mul(&a_x, &a_x, x)
543-
fe_add(maybe_yy, maybe_yy, &a_x)
540+
fe_a(&tmp)
541+
fe_mul(&tmp, &tmp, x)
542+
fe_add(&rhs, &rhs, &tmp)
544543

545-
fe_b(&b_fe)
546-
fe_add(maybe_yy, maybe_yy, &b_fe)
544+
fe_b(&tmp)
545+
fe_add(maybe_yy, &rhs, &tmp)
546+
547+
fe_clear(&rhs)
547548
}

core/crypto/_weierstrass/scalar_mul.odin

Lines changed: 159 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package _weierstrass
22

33
import "core:math/bits"
44
import "core:mem"
5-
import "core:slice"
65

76
pt_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")
5797
Multiply_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

Comments
 (0)