libsecp256k1_core/
ecmult.rs

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
42/// Context for accelerating the computation of a*P + b*G.
43pub struct ECMultContext {
44    pre_g: [AffineStorage; ECMULT_TABLE_SIZE_G],
45}
46
47impl ECMultContext {
48    /// Create a new `ECMultContext` from raw values.
49    ///
50    /// # Safety
51    /// The function is unsafe because incorrect value of `pre_g` can lead to
52    /// crypto logic failure. You most likely do not want to use this function,
53    /// but `ECMultContext::new_boxed`.
54    pub const unsafe fn new_from_raw(pre_g: [AffineStorage; ECMULT_TABLE_SIZE_G]) -> Self {
55        Self { pre_g }
56    }
57
58    /// Inspect raw values of `ECMultContext`.
59    pub fn inspect_raw(&self) -> &[AffineStorage; ECMULT_TABLE_SIZE_G] {
60        &self.pre_g
61    }
62
63    /// Generate a new `ECMultContext` on the heap. Note that this function is expensive.
64    pub fn new_boxed() -> Box<Self> {
65        // This unsafe block allocates a new, unitialized `ECMultContext` and
66        // then fills in the value. This is to avoid allocating it on stack
67        // because the struct is big. All values in `ECMultContext` are manually
68        // initialized after allocation.
69        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
88/// Set a batch of group elements equal to the inputs given in jacobian
89/// coordinates. Not constant time.
90pub 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
112/// Calculate the (modular) inverses of a batch of field
113/// elements. Requires the inputs' magnitudes to be at most 8. The
114/// output magnitudes are 1 (but not guaranteed to be
115/// normalized).
116pub 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
161/// Context for accelerating the computation of a*G.
162pub struct ECMultGenContext {
163    prec: [[AffineStorage; 16]; 64],
164    blind: Scalar,
165    initial: Jacobian,
166}
167
168impl ECMultGenContext {
169    /// Create a new `ECMultGenContext` from raw values.
170    ///
171    /// # Safety
172    /// The function is unsafe because incorrect value of `pre_g` can lead to
173    /// crypto logic failure. You most likely do not want to use this function,
174    /// but `ECMultGenContext::new_boxed`.
175    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    /// Inspect `ECMultGenContext` values.
184    pub fn inspect_raw(&self) -> &[[AffineStorage; 16]; 64] {
185        &self.prec
186    }
187
188    /// Generate a new `ECMultGenContext` on the heap. Note that this function is expensive.
189    pub fn new_boxed() -> Box<Self> {
190        // This unsafe block allocates a new, unitialized `ECMultGenContext` and
191        // then fills in the value. This is to avoid allocating it on stack
192        // because the struct is big. All values in `ECMultGenContext` are
193        // manually initialized after allocation.
194        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        // Construct a group element with no known corresponding scalar (nothing up my sleeve).
214        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        // Compute prec.
228        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    /* Note that we cannot handle even numbers by negating them to be
399     * odd, as is done in other implementations, since if our scalars
400     * were specified to have width < 256 for performance reasons,
401     * their negations would have width 256 and we'd lose any
402     * performance benefit. Instead, we use a technique from Section
403     * 4.2 of the Okeya/Tagaki paper, which is to add either 1 (for
404     * even) or 2 (for odd) to the number we are encoding, returning a
405     * skew value indicating this, and having the caller compensate
406     * after doing the multiplication. */
407
408    /* Negative numbers will be negated to keep their bit
409     * representation below the maximum width */
410    let flip = s.is_high();
411    /* We add 1 to even numbers, 2 to odd ones, noting that negation
412     * flips parity */
413    let bit = flip ^ !s.is_even();
414    /* We add 1 to even numbers, 2 to odd ones, noting that negation
415     * flips parity */
416    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    /* If we had negative one, flip == 1, s.d[0] == 0, bit == 1, so
420     * caller expects that we added two to it and flipped it. In fact
421     * for -1 these operations are identical. We only flipped, but
422     * since skewing is required (in the sense that the skew must be 1
423     * or 2, never zero) and flipping is not, we need to change our
424     * flags to claim that we only skewed. */
425    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        /* Calculate odd multiples of a.  All multiples are brought to
504         * the same Z 'denominator', which is stored in Z. Due to
505         * secp256k1' isomorphism we can do all operations pretending
506         * that the Z coordinate was 1, use affine addition formulae,
507         * and correct the Z coordinate of the result once at the end.
508         */
509        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        /* first loop iteration (separated out so we can directly set
516         * r, rather than having it start at infinity, get doubled
517         * several times, then have its new value added to it) */
518        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        /* remaining loop iterations */
524        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        /* Correct for wNAF skew */
539        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        /* For odd numbers this is 2a (so replace it), for even ones a (so no-op) */
550        correction_1_stor.cmov(&a2_stor, skew_1 == 2);
551
552        /* Apply the correction */
553        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}