poseidon_primitives/poseidon/primitives/
fields.rs

1/// Compute a + b + carry, returning the result and the new carry over.
2#[inline(always)]
3pub(crate) const fn adc(a: u64, b: u64, carry: u64) -> (u64, u64) {
4    let ret = (a as u128) + (b as u128) + (carry as u128);
5    (ret as u64, (ret >> 64) as u64)
6}
7
8/// Compute a - (b + borrow), returning the result and the new borrow.
9#[inline(always)]
10pub(crate) const fn sbb(a: u64, b: u64, borrow: u64) -> (u64, u64) {
11    let ret = (a as u128).wrapping_sub((b as u128) + ((borrow >> 63) as u128));
12    (ret as u64, (ret >> 64) as u64)
13}
14
15/// Compute a + (b * c) + carry, returning the result and the new carry over.
16#[inline(always)]
17pub(crate) const fn mac(a: u64, b: u64, c: u64, carry: u64) -> (u64, u64) {
18    let ret = (a as u128) + ((b as u128) * (c as u128)) + (carry as u128);
19    (ret as u64, (ret >> 64) as u64)
20}
21
22/// Compute a + (b * c), returning the result and the new carry over.
23#[inline(always)]
24pub(crate) const fn macx(a: u64, b: u64, c: u64) -> (u64, u64) {
25    let res = (a as u128) + ((b as u128) * (c as u128));
26    (res as u64, (res >> 64) as u64)
27}
28
29/// Compute a * b, returning the result.
30#[inline(always)]
31pub(crate) fn mul_512(a: [u64; 4], b: [u64; 4]) -> [u64; 8] {
32    let (r0, carry) = macx(0, a[0], b[0]);
33    let (r1, carry) = macx(carry, a[0], b[1]);
34    let (r2, carry) = macx(carry, a[0], b[2]);
35    let (r3, carry_out) = macx(carry, a[0], b[3]);
36
37    let (r1, carry) = macx(r1, a[1], b[0]);
38    let (r2, carry) = mac(r2, a[1], b[1], carry);
39    let (r3, carry) = mac(r3, a[1], b[2], carry);
40    let (r4, carry_out) = mac(carry_out, a[1], b[3], carry);
41
42    let (r2, carry) = macx(r2, a[2], b[0]);
43    let (r3, carry) = mac(r3, a[2], b[1], carry);
44    let (r4, carry) = mac(r4, a[2], b[2], carry);
45    let (r5, carry_out) = mac(carry_out, a[2], b[3], carry);
46
47    let (r3, carry) = macx(r3, a[3], b[0]);
48    let (r4, carry) = mac(r4, a[3], b[1], carry);
49    let (r5, carry) = mac(r5, a[3], b[2], carry);
50    let (r6, carry_out) = mac(carry_out, a[3], b[3], carry);
51
52    [r0, r1, r2, r3, r4, r5, r6, carry_out]
53}