Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor Fp code to use const generics, and more #379

Merged
merged 33 commits into from
Jan 31, 2022
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
0b1c3c5
`const` generics for `Fp` & no Montgomery default
Pratyush Jan 10, 2022
56e5ecc
More powerful compile-time Fp configuration
Pratyush Jan 11, 2022
8a81ee7
Fix compilation errors in `ark-ec`
Pratyush Jan 11, 2022
5fb6ffb
Fix compilation errors in `ark-poly`
Pratyush Jan 11, 2022
e8558d7
Fix doctest
Pratyush Jan 11, 2022
2a47811
Fix CHANGELOG typos
Pratyush Jan 11, 2022
fbede63
Everything compiles
Pratyush Jan 12, 2022
7ea854b
Rename `Parameters` to `Config` for all fields
Pratyush Jan 12, 2022
dfeea4a
Update CHANGELOG and fix typos in README
Pratyush Jan 12, 2022
ec89e31
Clean up CHANGELOG further
Pratyush Jan 12, 2022
cc8cb91
Fix assembly
Pratyush Jan 12, 2022
266b37e
Fix indentation
Pratyush Jan 12, 2022
ad1bca7
Fix assembly
Pratyush Jan 12, 2022
23868df
Fix README lint
Pratyush Jan 12, 2022
7a76bd8
Fix import
Pratyush Jan 12, 2022
9ce6ce9
Fix match statement
Pratyush Jan 12, 2022
b5f3887
Fix match statement, and move no_carry check to constant
Pratyush Jan 12, 2022
923bb3f
Introduce `BigInt` macro
Pratyush Jan 12, 2022
61fcbaf
Fix `CAPACITY` bug
Pratyush Jan 12, 2022
2e083db
Make `QuadExt` and `CubicExt` macros more succinct
Pratyush Jan 12, 2022
054204b
Add documentation for macros
Pratyush Jan 12, 2022
a550389
fmt
Pratyush Jan 12, 2022
5f866fe
Use singular in CHANGELOG
Pratyush Jan 12, 2022
2964946
Clean up some documentation
Pratyush Jan 12, 2022
bce28d3
Merge branch 'upgrade-ff' of github.com:arkworks-rs/algebra into upgr…
Pratyush Jan 12, 2022
5b6642f
Update and format
Pratyush Jan 12, 2022
9f01c8b
Clean up doc test
Pratyush Jan 12, 2022
0d8fcd1
Clean up docs
Pratyush Jan 12, 2022
6f5623a
Apply suggestions from code review
Pratyush Jan 15, 2022
76b0084
Update ff/src/fields/mod.rs
Pratyush Jan 15, 2022
b366b77
Clean up and format
Pratyush Jan 15, 2022
dc52c73
Remove `FftConfig` and move constants to `FftField`
Pratyush Jan 15, 2022
9ce092a
Update CHANGELOG
Pratyush Jan 15, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
206 changes: 107 additions & 99 deletions CHANGELOG.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion ec/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ categories = ["cryptography"]
include = ["Cargo.toml", "src", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
license = "MIT/Apache-2.0"
edition = "2021"
rust-version = "1.56"
rust-version = "1.57"

[dependencies]
ark-std = { version = "^0.3.0", default-features = false }
Expand Down
8 changes: 4 additions & 4 deletions ec/src/models/bls12/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ use crate::{
};
use ark_ff::fields::{
fp12_2over3over2::{Fp12, Fp12Parameters},
fp2::Fp2Parameters,
fp6_3over2::Fp6Parameters,
fp2::Fp2Config,
fp6_3over2::Fp6Config,
BitIteratorBE, Field, Fp2, PrimeField, SquareRootField,
};
use core::marker::PhantomData;
Expand Down Expand Up @@ -34,8 +34,8 @@ pub trait Bls12Parameters: 'static {
const TWIST_TYPE: TwistType;

type Fp: PrimeField + SquareRootField + Into<<Self::Fp as PrimeField>::BigInt>;
type Fp2Params: Fp2Parameters<Fp = Self::Fp>;
type Fp6Params: Fp6Parameters<Fp2Params = Self::Fp2Params>;
type Fp2Params: Fp2Config<Fp = Self::Fp>;
type Fp6Params: Fp6Config<Fp2Params = Self::Fp2Params>;
type Fp12Params: Fp12Parameters<Fp6Params = Self::Fp6Params>;
type G1Parameters: SWModelParameters<BaseField = Self::Fp>;
type G2Parameters: SWModelParameters<
Expand Down
8 changes: 4 additions & 4 deletions ec/src/models/bn/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ use crate::{
};
use ark_ff::fields::{
fp12_2over3over2::{Fp12, Fp12Parameters},
fp2::Fp2Parameters,
fp6_3over2::Fp6Parameters,
fp2::Fp2Config,
fp6_3over2::Fp6Config,
Field, Fp2, PrimeField, SquareRootField,
};
use num_traits::One;
Expand All @@ -32,8 +32,8 @@ pub trait BnParameters: 'static {
const TWIST_MUL_BY_Q_X: Fp2<Self::Fp2Params>;
const TWIST_MUL_BY_Q_Y: Fp2<Self::Fp2Params>;
type Fp: PrimeField + SquareRootField + Into<<Self::Fp as PrimeField>::BigInt>;
type Fp2Params: Fp2Parameters<Fp = Self::Fp>;
type Fp6Params: Fp6Parameters<Fp2Params = Self::Fp2Params>;
type Fp2Params: Fp2Config<Fp = Self::Fp>;
type Fp6Params: Fp6Config<Fp2Params = Self::Fp2Params>;
type Fp12Params: Fp12Parameters<Fp6Params = Self::Fp6Params>;
type G1Parameters: SWModelParameters<BaseField = Self::Fp>;
type G2Parameters: SWModelParameters<
Expand Down
8 changes: 4 additions & 4 deletions ec/src/models/bw6/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ use crate::{
PairingEngine,
};
use ark_ff::fields::{
fp3::Fp3Parameters,
fp6_2over3::{Fp6, Fp6Parameters},
fp3::Fp3Config,
fp6_2over3::{Fp6, Fp6Config},
BitIteratorBE, Field, PrimeField, SquareRootField,
};
use num_traits::One;
Expand All @@ -25,8 +25,8 @@ pub trait BW6Parameters: 'static + Eq + PartialEq {
const ATE_LOOP_COUNT_2_IS_NEGATIVE: bool;
const TWIST_TYPE: TwistType;
type Fp: PrimeField + SquareRootField + Into<<Self::Fp as PrimeField>::BigInt>;
type Fp3Params: Fp3Parameters<Fp = Self::Fp>;
type Fp6Params: Fp6Parameters<Fp3Params = Self::Fp3Params>;
type Fp3Params: Fp3Config<Fp = Self::Fp>;
type Fp6Params: Fp6Config<Fp3Params = Self::Fp3Params>;
type G1Parameters: SWModelParameters<BaseField = Self::Fp>;
type G2Parameters: SWModelParameters<
BaseField = Self::Fp,
Expand Down
8 changes: 4 additions & 4 deletions ec/src/models/mnt4/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ use crate::{
PairingEngine,
};
use ark_ff::{
fp2::{Fp2, Fp2Parameters},
fp4::{Fp4, Fp4Parameters},
fp2::{Fp2, Fp2Config},
fp4::{Fp4, Fp4Config},
BitIteratorBE, Field, PrimeField, SquareRootField,
};
use num_traits::{One, Zero};
Expand Down Expand Up @@ -32,8 +32,8 @@ pub trait MNT4Parameters: 'static {
const FINAL_EXPONENT_LAST_CHUNK_ABS_OF_W0: <Self::Fp as PrimeField>::BigInt;
type Fp: PrimeField + SquareRootField + Into<<Self::Fp as PrimeField>::BigInt>;
type Fr: PrimeField + SquareRootField + Into<<Self::Fr as PrimeField>::BigInt>;
type Fp2Params: Fp2Parameters<Fp = Self::Fp>;
type Fp4Params: Fp4Parameters<Fp2Params = Self::Fp2Params>;
type Fp2Params: Fp2Config<Fp = Self::Fp>;
type Fp4Params: Fp4Config<Fp2Params = Self::Fp2Params>;
type G1Parameters: SWModelParameters<BaseField = Self::Fp, ScalarField = Self::Fr>;
type G2Parameters: SWModelParameters<
BaseField = Fp2<Self::Fp2Params>,
Expand Down
8 changes: 4 additions & 4 deletions ec/src/models/mnt6/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ use crate::{
PairingEngine,
};
use ark_ff::{
fp3::{Fp3, Fp3Parameters},
fp6_2over3::{Fp6, Fp6Parameters},
fp3::{Fp3, Fp3Config},
fp6_2over3::{Fp6, Fp6Config},
BitIteratorBE, Field, PrimeField, SquareRootField,
};
use num_traits::{One, Zero};
Expand Down Expand Up @@ -32,8 +32,8 @@ pub trait MNT6Parameters: 'static {
const FINAL_EXPONENT_LAST_CHUNK_ABS_OF_W0: <Self::Fp as PrimeField>::BigInt;
type Fp: PrimeField + SquareRootField + Into<<Self::Fp as PrimeField>::BigInt>;
type Fr: PrimeField + SquareRootField + Into<<Self::Fr as PrimeField>::BigInt>;
type Fp3Params: Fp3Parameters<Fp = Self::Fp>;
type Fp6Params: Fp6Parameters<Fp3Params = Self::Fp3Params>;
type Fp3Params: Fp3Config<Fp = Self::Fp>;
type Fp6Params: Fp6Config<Fp3Params = Self::Fp3Params>;
type G1Parameters: SWModelParameters<BaseField = Self::Fp, ScalarField = Self::Fr>;
type G2Parameters: SWModelParameters<
BaseField = Fp3<Self::Fp3Params>,
Expand Down
2 changes: 1 addition & 1 deletion ec/src/models/short_weierstrass_jacobian.rs
Original file line number Diff line number Diff line change
Expand Up @@ -688,7 +688,7 @@ impl<'a, P: Parameters> SubAssign<&'a Self> for GroupProjective<P> {

impl<P: Parameters> MulAssign<P::ScalarField> for GroupProjective<P> {
fn mul_assign(&mut self, other: P::ScalarField) {
*self = self.mul(other.into_repr())
*self = self.mul(other.into_bigint())
Pratyush marked this conversation as resolved.
Show resolved Hide resolved
}
}

Expand Down
4 changes: 2 additions & 2 deletions ec/src/models/twisted_edwards_extended.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ impl<'a, P: Parameters> SubAssign<&'a Self> for GroupAffine<P> {

impl<P: Parameters> MulAssign<P::ScalarField> for GroupAffine<P> {
fn mul_assign(&mut self, other: P::ScalarField) {
*self = self.mul(other.into_repr()).into()
*self = self.mul(other.into_bigint()).into()
}
}

Expand Down Expand Up @@ -583,7 +583,7 @@ impl<'a, P: Parameters> SubAssign<&'a Self> for GroupProjective<P> {

impl<P: Parameters> MulAssign<P::ScalarField> for GroupProjective<P> {
fn mul_assign(&mut self, other: P::ScalarField) {
*self = self.mul(other.into_repr())
*self = self.mul(other.into_bigint())
}
}

Expand Down
6 changes: 3 additions & 3 deletions ec/src/msm/fixed_base.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::{AffineCurve, ProjectiveCurve};
use ark_ff::{BigInteger, FpParameters, PrimeField};
use ark_ff::{BigInteger, PrimeField};
use ark_std::{cfg_iter, cfg_iter_mut, vec::Vec};

#[cfg(feature = "parallel")]
Expand Down Expand Up @@ -63,8 +63,8 @@ impl FixedBase {
multiples_of_g: &[Vec<T::Affine>],
scalar: &T::ScalarField,
) -> T {
let modulus_size = <T::ScalarField as PrimeField>::Params::MODULUS_BITS as usize;
let scalar_val = scalar.into_repr().to_bits_le();
let modulus_size = T::ScalarField::MODULUS_BIT_SIZE as usize;
let scalar_val = scalar.into_bigint().to_bits_le();

let mut res = multiples_of_g[0][0].into_projective();
for outer in 0..outerc {
Expand Down
4 changes: 2 additions & 2 deletions ec/src/msm/variable_base/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ impl VariableBase {
super::ln_without_floats(size) + 2
};

let num_bits = <G::ScalarField as PrimeField>::Params::MODULUS_BITS as usize;
let fr_one = G::ScalarField::one().into_repr();
let num_bits = G::ScalarField::MODULUS_BIT_SIZE as usize;
let fr_one = G::ScalarField::one().into_bigint();

let zero = G::Projective::zero();
let window_starts: Vec<_> = (0..num_bits).step_by(c).collect();
Expand Down
2 changes: 1 addition & 1 deletion ec/src/wnaf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ impl WnafContext {
if 1 << (self.window_size - 1) > base_table.len() {
return None;
}
let scalar_wnaf = scalar.into_repr().find_wnaf(self.window_size).unwrap();
let scalar_wnaf = scalar.into_bigint().find_wnaf(self.window_size).unwrap();

let mut result = G::zero();

Expand Down
2 changes: 1 addition & 1 deletion ff-asm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ categories = ["cryptography"]
include = ["Cargo.toml", "src", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
license = "MIT/Apache-2.0"
edition = "2021"
rust-version = "1.56"
rust-version = "1.57"

[dependencies]
quote = "1.0.0"
Expand Down
4 changes: 2 additions & 2 deletions ff-asm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,9 +298,9 @@ fn generate_impl(num_limbs: usize, is_mul: bool) -> String {
if is_mul {
ctx.add_declaration("b", "r", "b");
}
ctx.add_declaration("modulus", "r", "&P::MODULUS.0");
ctx.add_declaration("modulus", "r", "&Self::MODULUS.0");
ctx.add_declaration("0", "i", "0u64");
ctx.add_declaration("mod_prime", "i", "P::INV");
ctx.add_declaration("mod_prime", "i", "Self::INV");

if num_limbs > MAX_REGS {
ctx.add_buffer(2 * num_limbs);
Expand Down
2 changes: 1 addition & 1 deletion ff/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ include = ["Cargo.toml", "build.rs", "src", "README.md", "LICENSE-APACHE", "LICE
license = "MIT/Apache-2.0"
edition = "2021"
build = "build.rs"
rust-version = "1.56"
rust-version = "1.57"

[dependencies]
ark-ff-asm = { version = "^0.3.0", path = "../ff-asm" }
Expand Down
20 changes: 10 additions & 10 deletions ff/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,33 +7,33 @@
</p>

This crate defines Finite Field traits and useful abstraction models that follow these traits.
Implementations of finite fields with concrete parameters can be found in [`arkworks-rs/curves`](https://github.com/arkworks-rs/curves/README.md) under `arkworks-rs/curves/<your favourite curve>/src/fields/`, which are used for some of the popular curves, such as a specific [`Fq`](https://github.com/arkworks-rs/curves/blob/master/bls12_381/src/fields/fq.rs) used in BLS-381.
Implementations of concrete finite fields for some popular elliptic curves can be found in [`arkworks-rs/curves`](https://github.com/arkworks-rs/curves/README.md) under `arkworks-rs/curves/<your favourite curve>/src/fields/`.

This crate contains two types of traits:

- `Field` traits: These define interfaces for manipulating field elements, such as addition, multiplication, inverses, square roots, and more.
- Field Parameters: holds the parameters defining the field in question. For extension fields, it also provides additional functionality required for the field, such as operations involving a (cubic or quadratic) non-residue used for constructing the field (`NONRESIDUE`).
- Field `Config`s: specifies the parameters defining the field in question. For extension fields, it also provides additional functionality required for the field, such as operations involving a (cubic or quadratic) non-residue used for constructing the field (`NONRESIDUE`).

The available field traits are:

- [`Field`](https://github.com/arkworks-rs/algebra/blob/master/ff/src/fields/mod.rs#L66) - Interface for the most generic finte field
- [`FftField`](https://github.com/arkworks-rs/algebra/blob/master/ff/src/fields/mod.rs#L275) - Exposes methods that allow for performing efficient FFTs on this field's elements
- [`PrimeField`](https://github.com/arkworks-rs/algebra/blob/master/ff/src/fields/mod.rs#L347) - Field with `p` (`p` prime) elements, later referred to as `Fp`.
- [`Field`](https://github.com/arkworks-rs/algebra/blob/master/ff/src/fields/mod.rs#L66) - Interface for a generic finite field.
- [`FftField`](https://github.com/arkworks-rs/algebra/blob/master/ff/src/fields/mod.rs#L275) - Exposes methods that allow for performing efficient FFTs on field elements.
- [`PrimeField`](https://github.com/arkworks-rs/algebra/blob/master/ff/src/fields/mod.rs#L347) - Field with a prime `p` number of elements, also referred to as `Fp`.
- [`SquareRootField`](https://github.com/arkworks-rs/algebra/blob/master/ff/src/fields/mod.rs#L431) - Interface for fields that support square-root operations

The models implemented are:

- [`Quadratic Extension`](https://github.com/arkworks-rs/algebra/blob/master/ff/src/fields/models/quadratic_extension.rs)
- [`QuadExtField`](https://github.com/arkworks-rs/algebra/blob/master/ff/src/fields/models/quadratic_extension.rs#L140) - Struct representing a quadratic extension field, in this case holding two elements
- [`QuadExtParameters`](https://github.com/arkworks-rs/algebra/blob/master/ff/src/fields/models/quadratic_extension.rs#L27) - Trait defining the necessary parameters needed to instantiate a Quadratic Extension Field
- [`QuadExtField`](https://github.com/arkworks-rs/algebra/blob/master/ff/src/fields/models/quadratic_extension.rs#L140) - Struct representing a quadratic extension field, in this case holding two base field elements
- [`QuadExtConfig`](https://github.com/arkworks-rs/algebra/blob/master/ff/src/fields/models/quadratic_extension.rs#L27) - Trait defining the necessary parameters needed to instantiate a Quadratic Extension Field
- [`Cubic Extension`](https://github.com/arkworks-rs/algebra/blob/master/ff/src/fields/models/cubic_extension.rs)
- [`CubicExtField`](https://github.com/arkworks-rs/algebra/blob/master/ff/src/fields/models/cubic_extension.rs#L72) - Struct representing a cubic extension field, holds three elements
- [`CubicExtParameters`](https://github.com/arkworks-rs/algebra/blob/master/ff/src/fields/models/cubic_extension.rs#L27) - Trait defining the necessary parameters needed to instantiate a Cubic Extension Field
- [`CubicExtField`](https://github.com/arkworks-rs/algebra/blob/master/ff/src/fields/models/cubic_extension.rs#L72) - Struct representing a cubic extension field, holds three base field elements
- [`CubicExtConfig`](https://github.com/arkworks-rs/algebra/blob/master/ff/src/fields/models/cubic_extension.rs#L27) - Trait defining the necessary parameters needed to instantiate a Cubic Extension Field

The above two models serve as abstractions for constructing the extension fields `Fp^m` directly (i.e. `m` equal 2 or 3) or for creating extension towers to arrive at higher `m`. The latter is done by applying the extensions iteratively, e.g. cubic extension over a quadratic extension field.

- [`Fp2`](https://github.com/arkworks-rs/algebra/blob/master/ff/src/fields/models/fp2.rs#L103) - Quadratic extension directly on the prime field, i.e. `BaseField == BasePrimeField`
- [`Fp3`](https://github.com/arkworks-rs/algebra/blob/master/ff/src/fields/models/fp3.rs#L54) - Cubic extension directly on the prime field, i.e. `BaseField == BasePrimeField`
- [`Fp6_2over3`](https://github.com/arkworks-rs/algebra/blob/master/ff/src/fields/models/fp6_2over3.rs#L48) - Extension tower: quadratic extension on a cubic extension field, i.e. `BaseField = Fp3`, but `BasePrimeField = Fp`.
- [`Fp6_3over2`](https://github.com/arkworks-rs/algebra/blob/master/ff/src/fields/models/fp6_3over2.rs#L49) - Extension tower, similar to the above except that the towering order is reversed: it's a cubic extension on a quadratic extension field, i.e. `BaseField = Fp2`, but `BasePrimeField = Fp`. Only this latter one is exported by default as `Fp6`.
- [`Fp12_2over3over2`](https://github.com/arkworks-rs/algebra/blob/master/ff/src/fields/models/fp12_2over3over2.rs#L83) - Extension tower: quadratic extension of the `Fp6_3over2`, i.e. `BaseField = Fp6`.
- [`Fp12_2over3over2`](https://github.com/arkworks-rs/algebra/blob/master/ff/src/fields/models/fp12_2over3over2.rs#L83) - Extension tower: quadratic extension of `Fp6_3over2`, i.e. `BaseField = Fp6`.
38 changes: 24 additions & 14 deletions ff/src/biginteger/arithmetic.rs
Original file line number Diff line number Diff line change
@@ -1,41 +1,51 @@
use ark_std::vec::Vec;

/// Calculate a + b + carry, returning the sum and modifying the
/// carry value.
macro_rules! adc {
($a:expr, $b:expr, &mut $carry:expr$(,)?) => {{
let tmp = ($a as u128) + ($b as u128) + ($carry as u128);

$carry = (tmp >> 64) as u64;

tmp as u64
}};
}

/// Calculate a + (b * c) + carry, returning the least significant digit
/// and setting carry to the most significant digit.
/// Calculate a + b + carry, returning the sum and modifying the
/// carry value.
#[inline(always)]
pub(crate) fn adc(a: u64, b: u64, carry: &mut u64) -> u64 {
adc!(a, b, &mut *carry)
}

macro_rules! mac_with_carry {
($a:expr, $b:expr, $c:expr, &mut $carry:expr$(,)?) => {{
let tmp = ($a as u128) + ($b as u128 * $c as u128) + ($carry as u128);

$carry = (tmp >> 64) as u64;

tmp as u64
}};
}

/// Calculate a - b - borrow, returning the result and modifying
/// the borrow value.
/// Calculate a + (b * c) + carry, returning the least significant digit
/// and setting carry to the most significant digit.
#[inline(always)]
pub(crate) fn mac_with_carry(a: u64, b: u64, c: u64, carry: &mut u64) -> u64 {
mac_with_carry!(a, b, c, &mut *carry)
}

#[macro_export]
macro_rules! sbb {
($a:expr, $b:expr, &mut $borrow:expr$(,)?) => {{
let tmp = (1u128 << 64) + ($a as u128) - ($b as u128) - ($borrow as u128);

$borrow = if tmp >> 64 == 0 { 1 } else { 0 };

tmp as u64
}};
}

/// Calculate a - b - borrow, returning the result and modifying
/// the borrow value.
#[inline(always)]
pub(crate) fn sbb(a: u64, b: u64, borrow: &mut u64) -> u64 {
sbb!(a, b, &mut *borrow)
}

/// Calculate a + b * c, returning the lower 64 bits of the result and setting
/// `carry` to the upper 64 bits.
#[inline(always)]
Expand Down Expand Up @@ -66,7 +76,7 @@ pub fn find_wnaf(num: &[u64]) -> Vec<i64> {
let mut borrow = 0;

for (a, b) in num.iter_mut().zip(other) {
*a = sbb!(*a, b, &mut borrow);
*a = sbb(*a, b, &mut borrow);
}
};
let add_nocarry = |num: &mut [u64], z: u64| {
Expand All @@ -75,7 +85,7 @@ pub fn find_wnaf(num: &[u64]) -> Vec<i64> {
let mut carry = 0;

for (a, b) in num.iter_mut().zip(other) {
*a = adc!(*a, b, &mut carry);
*a = adc(*a, b, &mut carry);
}
};
let div2 = |num: &mut [u64]| {
Expand Down
Loading