1use crate::CurveExt;
8
9pub(crate) struct EndoParameters {
10 pub(crate) gamma1: [u64; 4],
11 pub(crate) gamma2: [u64; 4],
12 pub(crate) b1: [u64; 4],
13 pub(crate) b2: [u64; 4],
14}
15
16pub trait CurveEndo: CurveExt {
17 fn decompose_scalar(e: &Self::ScalarExt) -> (u128, bool, u128, bool);
18}
19
20#[inline(always)]
22pub(crate) const fn adc(a: u64, b: u64, carry: u64) -> (u64, u64) {
23 let ret = (a as u128) + (b as u128) + (carry as u128);
24 (ret as u64, (ret >> 64) as u64)
25}
26
27#[inline(always)]
29pub(crate) const fn sbb(a: u64, b: u64, borrow: u64) -> (u64, u64) {
30 let ret = (a as u128).wrapping_sub((b as u128) + ((borrow >> 63) as u128));
31 (ret as u64, (ret >> 64) as u64)
32}
33
34#[inline(always)]
36pub(crate) const fn mac(a: u64, b: u64, c: u64, carry: u64) -> (u64, u64) {
37 let ret = (a as u128) + ((b as u128) * (c as u128)) + (carry as u128);
38 (ret as u64, (ret >> 64) as u64)
39}
40
41#[inline(always)]
43pub(crate) const fn macx(a: u64, b: u64, c: u64) -> (u64, u64) {
44 let res = (a as u128) + ((b as u128) * (c as u128));
45 (res as u64, (res >> 64) as u64)
46}
47
48#[inline(always)]
50pub(crate) fn mul_512(a: [u64; 4], b: [u64; 4]) -> [u64; 8] {
51 let (r0, carry) = macx(0, a[0], b[0]);
52 let (r1, carry) = macx(carry, a[0], b[1]);
53 let (r2, carry) = macx(carry, a[0], b[2]);
54 let (r3, carry_out) = macx(carry, a[0], b[3]);
55
56 let (r1, carry) = macx(r1, a[1], b[0]);
57 let (r2, carry) = mac(r2, a[1], b[1], carry);
58 let (r3, carry) = mac(r3, a[1], b[2], carry);
59 let (r4, carry_out) = mac(carry_out, a[1], b[3], carry);
60
61 let (r2, carry) = macx(r2, a[2], b[0]);
62 let (r3, carry) = mac(r3, a[2], b[1], carry);
63 let (r4, carry) = mac(r4, a[2], b[2], carry);
64 let (r5, carry_out) = mac(carry_out, a[2], b[3], carry);
65
66 let (r3, carry) = macx(r3, a[3], b[0]);
67 let (r4, carry) = mac(r4, a[3], b[1], carry);
68 let (r5, carry) = mac(r5, a[3], b[2], carry);
69 let (r6, carry_out) = mac(carry_out, a[3], b[3], carry);
70
71 [r0, r1, r2, r3, r4, r5, r6, carry_out]
72}