1use crate::{
2 field::Field,
3 group::{globalz_set_table_gej, set_table_gej_var, Affine, AffineStorage, Jacobian, AFFINE_G},
4 scalar::Scalar,
5};
6use alloc::{
7 alloc::{alloc, Layout},
8 boxed::Box,
9 vec,
10 vec::Vec,
11};
12use subtle::Choice;
13
14pub const WINDOW_A: usize = 5;
15pub const WINDOW_G: usize = 16;
16pub const ECMULT_TABLE_SIZE_A: usize = 1 << (WINDOW_A - 2);
17pub const ECMULT_TABLE_SIZE_G: usize = 1 << (WINDOW_G - 2);
18pub const WNAF_BITS: usize = 256;
19
20fn odd_multiples_table_storage_var(pre: &mut [AffineStorage], a: &Jacobian) {
21 let mut prej: Vec<Jacobian> = Vec::with_capacity(pre.len());
22 for _ in 0..pre.len() {
23 prej.push(Jacobian::default());
24 }
25 let mut prea: Vec<Affine> = Vec::with_capacity(pre.len());
26 for _ in 0..pre.len() {
27 prea.push(Affine::default());
28 }
29 let mut zr: Vec<Field> = Vec::with_capacity(pre.len());
30 for _ in 0..pre.len() {
31 zr.push(Field::default());
32 }
33
34 odd_multiples_table(&mut prej, &mut zr, a);
35 set_table_gej_var(&mut prea, &prej, &zr);
36
37 for i in 0..pre.len() {
38 pre[i] = prea[i].into();
39 }
40}
41
42pub struct ECMultContext {
44 pre_g: [AffineStorage; ECMULT_TABLE_SIZE_G],
45}
46
47impl ECMultContext {
48 pub const unsafe fn new_from_raw(pre_g: [AffineStorage; ECMULT_TABLE_SIZE_G]) -> Self {
55 Self { pre_g }
56 }
57
58 pub fn inspect_raw(&self) -> &[AffineStorage; ECMULT_TABLE_SIZE_G] {
60 &self.pre_g
61 }
62
63 pub fn new_boxed() -> Box<Self> {
65 let mut this = unsafe {
70 let ptr = alloc(Layout::new::<ECMultContext>()) as *mut ECMultContext;
71 let mut this = Box::from_raw(ptr);
72
73 for i in 0..ECMULT_TABLE_SIZE_G {
74 this.pre_g[i] = AffineStorage::default();
75 }
76
77 this
78 };
79
80 let mut gj = Jacobian::default();
81 gj.set_ge(&AFFINE_G);
82 odd_multiples_table_storage_var(&mut this.pre_g, &gj);
83
84 this
85 }
86}
87
88pub fn set_all_gej_var(a: &[Jacobian]) -> Vec<Affine> {
91 let mut az: Vec<Field> = Vec::with_capacity(a.len());
92 for point in a {
93 if !point.is_infinity() {
94 az.push(point.z);
95 }
96 }
97 let azi: Vec<Field> = inv_all_var(&az);
98
99 let mut ret = vec![Affine::default(); a.len()];
100
101 let mut count = 0;
102 for i in 0..a.len() {
103 ret[i].infinity = a[i].infinity;
104 if !a[i].is_infinity() {
105 ret[i].set_gej_zinv(&a[i], &azi[count]);
106 count += 1;
107 }
108 }
109 ret
110}
111
112pub fn inv_all_var(fields: &[Field]) -> Vec<Field> {
117 if fields.is_empty() {
118 return Vec::new();
119 }
120
121 let mut ret = Vec::with_capacity(fields.len());
122 ret.push(fields[0]);
123
124 for i in 1..fields.len() {
125 ret.push(Field::default());
126 ret[i] = ret[i - 1] * fields[i];
127 }
128
129 let mut u = ret[fields.len() - 1].inv_var();
130
131 for i in (1..fields.len()).rev() {
132 let j = i;
133 let i = i - 1;
134 ret[j] = ret[i] * u;
135 u *= fields[j];
136 }
137
138 ret[0] = u;
139 ret
140}
141
142const GEN_BLIND: Scalar = Scalar([
143 2217680822, 850875797, 1046150361, 1330484644, 4015777837, 2466086288, 2052467175, 2084507480,
144]);
145const GEN_INITIAL: Jacobian = Jacobian {
146 x: Field::new_raw(
147 586608, 43357028, 207667908, 262670128, 142222828, 38529388, 267186148, 45417712,
148 115291924, 13447464,
149 ),
150 y: Field::new_raw(
151 12696548, 208302564, 112025180, 191752716, 143238548, 145482948, 228906000, 69755164,
152 243572800, 210897016,
153 ),
154 z: Field::new_raw(
155 3685368, 75404844, 20246216, 5748944, 73206666, 107661790, 110806176, 73488774, 5707384,
156 104448710,
157 ),
158 infinity: false,
159};
160
161pub struct ECMultGenContext {
163 prec: [[AffineStorage; 16]; 64],
164 blind: Scalar,
165 initial: Jacobian,
166}
167
168impl ECMultGenContext {
169 pub const unsafe fn new_from_raw(prec: [[AffineStorage; 16]; 64]) -> Self {
176 Self {
177 prec,
178 blind: GEN_BLIND,
179 initial: GEN_INITIAL,
180 }
181 }
182
183 pub fn inspect_raw(&self) -> &[[AffineStorage; 16]; 64] {
185 &self.prec
186 }
187
188 pub fn new_boxed() -> Box<Self> {
190 let mut this = unsafe {
195 let ptr = alloc(Layout::new::<ECMultGenContext>()) as *mut ECMultGenContext;
196 let mut this = Box::from_raw(ptr);
197
198 for j in 0..64 {
199 for i in 0..16 {
200 this.prec[j][i] = AffineStorage::default();
201 }
202 }
203
204 this.blind = GEN_BLIND;
205 this.initial = GEN_INITIAL;
206
207 this
208 };
209
210 let mut gj = Jacobian::default();
211 gj.set_ge(&AFFINE_G);
212
213 let mut nums_32 = [0u8; 32];
215 debug_assert!(b"The scalar for this x is unknown".len() == 32);
216 for (i, v) in b"The scalar for this x is unknown".iter().enumerate() {
217 nums_32[i] = *v;
218 }
219 let mut nums_x = Field::default();
220 assert!(nums_x.set_b32(&nums_32));
221 let mut nums_ge = Affine::default();
222 assert!(nums_ge.set_xo_var(&nums_x, false));
223 let mut nums_gej = Jacobian::default();
224 nums_gej.set_ge(&nums_ge);
225 nums_gej = nums_gej.add_ge_var(&AFFINE_G, None);
226
227 let mut precj: Vec<Jacobian> = Vec::with_capacity(1024);
229 for _ in 0..1024 {
230 precj.push(Jacobian::default());
231 }
232 let mut gbase = gj;
233 let mut numsbase = nums_gej;
234 for j in 0..64 {
235 precj[j * 16] = numsbase;
236 for i in 1..16 {
237 precj[j * 16 + i] = precj[j * 16 + i - 1].add_var(&gbase, None);
238 }
239 for _ in 0..4 {
240 gbase = gbase.double_var(None);
241 }
242 numsbase = numsbase.double_var(None);
243 if j == 62 {
244 numsbase = numsbase.neg();
245 numsbase = numsbase.add_var(&nums_gej, None);
246 }
247 }
248 let prec = set_all_gej_var(&precj);
249
250 for j in 0..64 {
251 for i in 0..16 {
252 let pg: AffineStorage = prec[j * 16 + i].into();
253 this.prec[j][i] = pg;
254 }
255 }
256
257 this
258 }
259}
260
261pub fn odd_multiples_table(prej: &mut [Jacobian], zr: &mut [Field], a: &Jacobian) {
262 debug_assert!(prej.len() == zr.len());
263 debug_assert!(!prej.is_empty());
264 debug_assert!(!a.is_infinity());
265
266 let d = a.double_var(None);
267 let d_ge = Affine {
268 x: d.x,
269 y: d.y,
270 infinity: false,
271 };
272
273 let mut a_ge = Affine::default();
274 a_ge.set_gej_zinv(a, &d.z);
275 prej[0].x = a_ge.x;
276 prej[0].y = a_ge.y;
277 prej[0].z = a.z;
278 prej[0].infinity = false;
279
280 zr[0] = d.z;
281 for i in 1..prej.len() {
282 prej[i] = prej[i - 1].add_ge_var(&d_ge, Some(&mut zr[i]));
283 }
284
285 let l = prej.last().unwrap().z * d.z;
286 prej.last_mut().unwrap().z = l;
287}
288
289fn odd_multiples_table_globalz_windowa(
290 pre: &mut [Affine; ECMULT_TABLE_SIZE_A],
291 globalz: &mut Field,
292 a: &Jacobian,
293) {
294 let mut prej: [Jacobian; ECMULT_TABLE_SIZE_A] = Default::default();
295 let mut zr: [Field; ECMULT_TABLE_SIZE_A] = Default::default();
296
297 odd_multiples_table(&mut prej, &mut zr, a);
298 globalz_set_table_gej(pre, globalz, &prej, &zr);
299}
300
301fn table_get_ge(r: &mut Affine, pre: &[Affine], n: i32, w: usize) {
302 debug_assert!(n & 1 == 1);
303 debug_assert!(n >= -((1 << (w - 1)) - 1));
304 debug_assert!(n <= ((1 << (w - 1)) - 1));
305 if n > 0 {
306 *r = pre[((n - 1) / 2) as usize];
307 } else {
308 *r = pre[((-n - 1) / 2) as usize].neg();
309 }
310}
311
312fn table_get_ge_const(r: &mut Affine, pre: &[Affine], n: i32, w: usize) {
313 let abs_n = n * (if n > 0 { 1 } else { 0 } * 2 - 1);
314 let idx_n = abs_n / 2;
315 debug_assert!(n & 1 == 1);
316 debug_assert!(n >= -((1 << (w - 1)) - 1));
317 debug_assert!(n <= ((1 << (w - 1)) - 1));
318 for m in 0..pre.len() {
319 let flag = m == idx_n as usize;
320 r.x.cmov(&pre[m].x, flag);
321 r.y.cmov(&pre[m].y, flag);
322 }
323 r.infinity = false;
324 let neg_y = r.y.neg(1);
325 r.y.cmov(&neg_y, n != abs_n);
326}
327
328fn table_get_ge_storage(r: &mut Affine, pre: &[AffineStorage], n: i32, w: usize) {
329 debug_assert!(n & 1 == 1);
330 debug_assert!(n >= -((1 << (w - 1)) - 1));
331 debug_assert!(n <= ((1 << (w - 1)) - 1));
332 if n > 0 {
333 *r = pre[((n - 1) / 2) as usize].into();
334 } else {
335 *r = pre[((-n - 1) / 2) as usize].into();
336 *r = r.neg();
337 }
338}
339
340pub fn ecmult_wnaf(wnaf: &mut [i32], a: &Scalar, w: usize) -> i32 {
341 let mut s = *a;
342 let mut last_set_bit: i32 = -1;
343 let mut bit = 0;
344 let mut sign = 1;
345 let mut carry = 0;
346
347 debug_assert!(wnaf.len() <= 256);
348 debug_assert!(w >= 2 && w <= 31);
349
350 for i in 0..wnaf.len() {
351 wnaf[i] = 0;
352 }
353
354 if s.bits(255, 1) > 0 {
355 s = -s;
356 sign = -1;
357 }
358
359 while bit < wnaf.len() {
360 let mut now;
361 let mut word;
362 if s.bits(bit, 1) == carry as u32 {
363 bit += 1;
364 continue;
365 }
366
367 now = w;
368 if now > wnaf.len() - bit {
369 now = wnaf.len() - bit;
370 }
371
372 word = (s.bits_var(bit, now) as i32) + carry;
373
374 carry = (word >> (w - 1)) & 1;
375 word -= carry << w;
376
377 wnaf[bit] = sign * word;
378 last_set_bit = bit as i32;
379
380 bit += now;
381 }
382 debug_assert!(carry == 0);
383 debug_assert!({
384 let mut t = true;
385 while bit < 256 {
386 t = t && (s.bits(bit, 1) == 0);
387 bit += 1;
388 }
389 t
390 });
391 last_set_bit + 1
392}
393
394pub fn ecmult_wnaf_const(wnaf: &mut [i32], a: &Scalar, w: usize) -> i32 {
395 let mut s = *a;
396 let mut word = 0;
397
398 let flip = s.is_high();
411 let bit = flip ^ !s.is_even();
414 let neg_s = -s;
417 let not_neg_one = !neg_s.is_one();
418 s.cadd_bit(if bit { 1 } else { 0 }, not_neg_one);
419 let mut global_sign = if flip { -1 } else { 1 };
426 s.cond_neg_assign(Choice::from(flip as u8));
427 global_sign *= if not_neg_one { 1 } else { 0 } * 2 - 1;
428 let skew = 1 << (if bit { 1 } else { 0 });
429
430 let mut u_last: i32 = s.shr_int(w) as i32;
431 let mut u: i32 = 0;
432 while word * w < WNAF_BITS {
433 u = s.shr_int(w) as i32;
434 let even = (u & 1) == 0;
435 let sign = 2 * (if u_last > 0 { 1 } else { 0 }) - 1;
436 u += sign * if even { 1 } else { 0 };
437 u_last -= sign * if even { 1 } else { 0 } * (1 << w);
438
439 wnaf[word] = (u_last as i32 * global_sign as i32) as i32;
440 word += 1;
441
442 u_last = u;
443 }
444 wnaf[word] = u * global_sign as i32;
445
446 debug_assert!(s.is_zero());
447 let wnaf_size = (WNAF_BITS + w - 1) / w;
448 debug_assert!(word == wnaf_size);
449
450 skew
451}
452
453impl ECMultContext {
454 pub fn ecmult(&self, r: &mut Jacobian, a: &Jacobian, na: &Scalar, ng: &Scalar) {
455 let mut tmpa = Affine::default();
456 let mut pre_a: [Affine; ECMULT_TABLE_SIZE_A] = Default::default();
457 let mut z = Field::default();
458 let mut wnaf_na = [0i32; 256];
459 let mut wnaf_ng = [0i32; 256];
460 let bits_na = ecmult_wnaf(&mut wnaf_na, na, WINDOW_A);
461 let mut bits = bits_na;
462 odd_multiples_table_globalz_windowa(&mut pre_a, &mut z, a);
463
464 let bits_ng = ecmult_wnaf(&mut wnaf_ng, &ng, WINDOW_G);
465 if bits_ng > bits {
466 bits = bits_ng;
467 }
468
469 r.set_infinity();
470 for i in (0..bits).rev() {
471 let mut n;
472 *r = r.double_var(None);
473
474 n = wnaf_na[i as usize];
475 if i < bits_na && n != 0 {
476 table_get_ge(&mut tmpa, &pre_a, n, WINDOW_A);
477 *r = r.add_ge_var(&tmpa, None);
478 }
479 n = wnaf_ng[i as usize];
480 if i < bits_ng && n != 0 {
481 table_get_ge_storage(&mut tmpa, &self.pre_g, n, WINDOW_G);
482 *r = r.add_zinv_var(&tmpa, &z);
483 }
484 }
485
486 if !r.is_infinity() {
487 r.z *= &z;
488 }
489 }
490
491 pub fn ecmult_const(&self, r: &mut Jacobian, a: &Affine, scalar: &Scalar) {
492 const WNAF_SIZE: usize = (WNAF_BITS + (WINDOW_A - 1) - 1) / (WINDOW_A - 1);
493
494 let mut tmpa = Affine::default();
495 let mut pre_a: [Affine; ECMULT_TABLE_SIZE_A] = Default::default();
496 let mut z = Field::default();
497
498 let mut wnaf_1 = [0i32; 1 + WNAF_SIZE];
499
500 let sc = *scalar;
501 let skew_1 = ecmult_wnaf_const(&mut wnaf_1, &sc, WINDOW_A - 1);
502
503 r.set_ge(a);
510 odd_multiples_table_globalz_windowa(&mut pre_a, &mut z, r);
511 for i in 0..ECMULT_TABLE_SIZE_A {
512 pre_a[i].y.normalize_weak();
513 }
514
515 let i = wnaf_1[WNAF_SIZE];
519 debug_assert!(i != 0);
520 table_get_ge_const(&mut tmpa, &pre_a, i, WINDOW_A);
521 r.set_ge(&tmpa);
522
523 for i in (0..WNAF_SIZE).rev() {
525 for _ in 0..(WINDOW_A - 1) {
526 let r2 = *r;
527 r.double_nonzero_in_place(&r2, None);
528 }
529
530 let n = wnaf_1[i];
531 table_get_ge_const(&mut tmpa, &pre_a, n, WINDOW_A);
532 debug_assert!(n != 0);
533 *r = r.add_ge(&tmpa);
534 }
535
536 r.z *= &z;
537
538 let mut correction = *a;
540 let mut correction_1_stor: AffineStorage;
541 let a2_stor: AffineStorage;
542 let mut tmpj = Jacobian::default();
543 tmpj.set_ge(&correction);
544 tmpj = tmpj.double_var(None);
545 correction.set_gej(&tmpj);
546 correction_1_stor = (*a).into();
547 a2_stor = correction.into();
548
549 correction_1_stor.cmov(&a2_stor, skew_1 == 2);
551
552 correction = correction_1_stor.into();
554 correction = correction.neg();
555 *r = r.add_ge(&correction)
556 }
557}
558
559impl ECMultGenContext {
560 pub fn ecmult_gen(&self, r: &mut Jacobian, gn: &Scalar) {
561 let mut adds = AffineStorage::default();
562 *r = self.initial;
563
564 let mut gnb = gn + &self.blind;
565 let mut add = Affine::default();
566 add.infinity = false;
567
568 for j in 0..64 {
569 let mut bits = gnb.bits(j * 4, 4);
570 for i in 0..16 {
571 adds.cmov(&self.prec[j][i], i as u32 == bits);
572 }
573 add = adds.into();
574 *r = r.add_ge(&add);
575 #[allow(unused_assignments)]
576 {
577 bits = 0;
578 }
579 }
580 add.clear();
581 gnb.clear();
582 }
583}