Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
e610dae
Modularize multiplication by small constants. Allow for turning large…
mathmasterzach Aug 14, 2025
d91c33f
revert extra bn254 change
mathmasterzach Aug 14, 2025
8669d83
add fma for multiplication by u64
mathmasterzach Aug 14, 2025
f72f76c
fix bench
quangvdao Aug 15, 2025
4786b21
use mac_with_carry rather than hand-written code
quangvdao Aug 15, 2025
3a31318
added test for new bigint mul
quangvdao Aug 15, 2025
64af2cb
added uncheck nplus3 conversion
quangvdao Aug 15, 2025
317d509
odd speedup in barrett reduce
mathmasterzach Aug 15, 2025
79f2614
added fma into nplus4
quangvdao Aug 16, 2025
1ae55ed
refactor mul by high limbs
quangvdao Aug 16, 2025
1756d8b
added signed bigint
quangvdao Aug 22, 2025
433529b
more additions to (signed) bigint
quangvdao Aug 22, 2025
ebb26fd
new materials for svo
quangvdao Aug 25, 2025
6bdb726
Merge remote-tracking branch 'origin/feat/msm-i64-i128' into feat/few…
quangvdao Sep 9, 2025
a7329f7
feat: adding support for MontU128
abiswas3 Sep 9, 2025
f82ee9f
Merge branch 'dev/twist-shout' of https://github.com/a16z/arkworks-al…
abiswas3 Sep 9, 2025
b1a97cb
feat: small binding mult (CIOS with zeros)
Sep 12, 2025
737c603
WIP, add bigint `add_trunc`
quangvdao Sep 13, 2025
791be0d
added new types for small value
quangvdao Sep 16, 2025
46588d7
feat: adding support for MontU128
abiswas3 Sep 16, 2025
a90d709
Merge branch 'dev/twist-shout' of https://github.com/abiswas3/arkwork…
abiswas3 Sep 16, 2025
ab80fd9
make allocative default, add more custom type ops
quangvdao Sep 16, 2025
7fac065
(de)serialization & allocative for i8 or i96
quangvdao Sep 16, 2025
93250cc
add conversion from (signed) bigint to field elts
quangvdao Sep 16, 2025
1e03fd6
starting refactor / unification of new bigint ops
quangvdao Sep 16, 2025
7277b2e
add msm for s64 and s128
quangvdao Sep 16, 2025
ddb9805
add conversion traits for S160
quangvdao Sep 16, 2025
1901417
added default to SignedBigInt
quangvdao Sep 16, 2025
6cb3aa1
fixing multiplication bug
quangvdao Sep 17, 2025
001264f
add new API for add/sub/mul bigint of different widths + generic mont…
quangvdao Sep 24, 2025
4ac8b20
fix generic mont reduce
quangvdao Sep 24, 2025
6d72edc
fewer copy in generic mont reduce
quangvdao Sep 24, 2025
127a131
Merge branch 'feat/fewer-reductions' into dev/twist-shout
abiswas3 Sep 25, 2025
9acb9b7
Duplicate functions removed - quang and my code overlapped
abiswas3 Sep 25, 2025
1c010c4
Merge branch 'feat/fewer-reductions' into dev/twist-shout
abiswas3 Sep 25, 2025
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
6 changes: 2 additions & 4 deletions bench-templates/src/macros/field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -405,16 +405,14 @@ macro_rules! prime_field {
f[i].into_bigint()
})
});
let u64s = (0..SAMPLES)
.map(|_| rng.next_u64())
.collect::<Vec<_>>();
let u64s = (0..SAMPLES).map(|_| rng.next_u64()).collect::<Vec<_>>();
conversions.bench_function("From u64", |b| {
let mut i = 0;
b.iter(|| {
i = (i + 1) % SAMPLES;
<$F>::from_u64(u64s[i])
})
});
});
conversions.finish()
}
};
Expand Down
6 changes: 1 addition & 5 deletions ec/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,7 @@ use ark_std::{
ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign},
vec::*,
};
pub use scalar_mul::{
fixed_base::FixedBase,
variable_base::VariableBaseMSM,
ScalarMul,
};
pub use scalar_mul::{fixed_base::FixedBase, variable_base::VariableBaseMSM, ScalarMul};
use zeroize::Zeroize;

pub use ark_ff::AdditiveGroup;
Expand Down
1 change: 0 additions & 1 deletion ec/src/models/short_weierstrass/affine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,6 @@ impl<P: SWCurveConfig> AffineRepr for Affine<P> {

/// Multiplies this element by the cofactor and output the
/// resulting projective element.
#[must_use]
fn mul_by_cofactor_to_group(&self) -> Self::Group {
P::mul_affine(self, Self::Config::COFACTOR)
}
Expand Down
1 change: 0 additions & 1 deletion ec/src/models/twisted_edwards/affine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,6 @@ impl<P: TECurveConfig> AffineRepr for Affine<P> {

/// Multiplies this element by the cofactor and output the
/// resulting projective element.
#[must_use]
fn mul_by_cofactor_to_group(&self) -> Self::Group {
P::mul_affine(self, Self::Config::COFACTOR)
}
Expand Down
10 changes: 8 additions & 2 deletions ec/src/pairing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,14 @@ pub trait Pairing: Sized + 'static + Copy + Debug + Sync + Send + Eq {
a: impl IntoIterator<Item = impl AsRef<Self::G1Prepared>>,
b: impl IntoIterator<Item = impl AsRef<Self::G2Prepared>>,
) -> MillerLoopOutput<Self> {
let a_cloned = a.into_iter().map(|x| x.as_ref().clone()).collect::<Vec<_>>();
let b_cloned = b.into_iter().map(|x| x.as_ref().clone()).collect::<Vec<_>>();
let a_cloned = a
.into_iter()
.map(|x| x.as_ref().clone())
.collect::<Vec<_>>();
let b_cloned = b
.into_iter()
.map(|x| x.as_ref().clone())
.collect::<Vec<_>>();
Self::multi_miller_loop(a_cloned, b_cloned)
}

Expand Down
2 changes: 1 addition & 1 deletion ec/src/scalar_mul/fixed_base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,4 +95,4 @@ impl FixedBase {
.map(|e| Self::windowed_mul::<T>(outerc, window, table, e))
.collect::<Vec<_>>()
}
}
}
2 changes: 1 addition & 1 deletion ec/src/scalar_mul/mod.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
pub mod glv;
pub mod wnaf;

pub mod variable_base;
pub mod fixed_base;
pub mod variable_base;

use crate::{
short_weierstrass::{Affine, Projective, SWCurveConfig},
Expand Down
97 changes: 97 additions & 0 deletions ec/src/scalar_mul/variable_base/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use ark_ff::prelude::*;
use ark_ff::biginteger::{S128, S64};
use ark_std::{
borrow::Borrow,
cfg_chunks, cfg_into_iter, cfg_iter,
Expand Down Expand Up @@ -626,6 +627,102 @@ pub fn msm_i128<V: VariableBaseMSM>(
}
}

pub fn msm_s64<V: VariableBaseMSM>(
mut bases: &[V::MulBase],
mut scalars: &[S64],
serial: bool,
) -> V {
let (negative_bases, non_negative_bases): (Vec<V::MulBase>, Vec<V::MulBase>) =
bases.iter().enumerate().partition_map(|(i, b)| {
if !scalars[i].sign() {
Either::Left(b)
} else {
Either::Right(b)
}
});
let (negative_scalars, non_negative_scalars): (Vec<u64>, Vec<u64>) = scalars
.iter()
.partition_map(|s| {
let mag = s.magnitude_as_u64();
if !s.sign() {
Either::Left(mag)
} else {
Either::Right(mag)
}
});
if serial {
return msm_serial::<V, _>(&non_negative_bases, &non_negative_scalars)
- msm_serial::<V, _>(&negative_bases, &negative_scalars);
} else {
let chunk_size = match preamble(&mut bases, &mut scalars, serial) {
Some(chunk_size) => chunk_size,
None => return V::zero(),
};

let non_negative_msm: V = cfg_chunks!(non_negative_bases, chunk_size)
.zip(cfg_chunks!(non_negative_scalars, chunk_size))
.map(|(non_negative_bases, non_negative_scalars)| {
msm_serial::<V, _>(non_negative_bases, non_negative_scalars)
})
.sum();
let negative_msm: V = cfg_chunks!(negative_bases, chunk_size)
.zip(cfg_chunks!(negative_scalars, chunk_size))
.map(|(negative_bases, negative_scalars)| {
msm_serial::<V, _>(negative_bases, negative_scalars)
})
.sum();
non_negative_msm - negative_msm
}
}

pub fn msm_s128<V: VariableBaseMSM>(
mut bases: &[V::MulBase],
mut scalars: &[S128],
serial: bool,
) -> V {
let (negative_bases, non_negative_bases): (Vec<V::MulBase>, Vec<V::MulBase>) =
bases.iter().enumerate().partition_map(|(i, b)| {
if !scalars[i].sign() {
Either::Left(b)
} else {
Either::Right(b)
}
});
let (negative_scalars, non_negative_scalars): (Vec<u128>, Vec<u128>) = scalars
.iter()
.partition_map(|s| {
let mag = s.magnitude_as_u128();
if !s.sign() {
Either::Left(mag)
} else {
Either::Right(mag)
}
});
if serial {
return msm_serial::<V, _>(&non_negative_bases, &non_negative_scalars)
- msm_serial::<V, _>(&negative_bases, &negative_scalars);
} else {
let chunk_size = match preamble(&mut bases, &mut scalars, serial) {
Some(chunk_size) => chunk_size,
None => return V::zero(),
};

let non_negative_msm: V = cfg_chunks!(non_negative_bases, chunk_size)
.zip(cfg_chunks!(non_negative_scalars, chunk_size))
.map(|(non_negative_bases, non_negative_scalars)| {
msm_serial::<V, _>(non_negative_bases, non_negative_scalars)
})
.sum();
let negative_msm: V = cfg_chunks!(negative_bases, chunk_size)
.zip(cfg_chunks!(negative_scalars, chunk_size))
.map(|(negative_bases, negative_scalars)| {
msm_serial::<V, _>(negative_bases, negative_scalars)
})
.sum();
non_negative_msm - negative_msm
}
}

pub fn msm_u128<V: VariableBaseMSM>(
mut bases: &[V::MulBase],
mut scalars: &[u128],
Expand Down
3 changes: 1 addition & 2 deletions ff/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ zeroize = { workspace = true, features = ["zeroize_derive"] }
num-bigint.workspace = true
digest = { workspace = true, features = ["alloc"] }
itertools.workspace = true
allocative = { version = "0.3.4", optional = true }
allocative = "0.3.4"

[dev-dependencies]
ark-test-curves = { workspace = true, features = [
Expand All @@ -53,4 +53,3 @@ default = []
std = ["ark-std/std", "ark-serialize/std", "itertools/use_std"]
parallel = ["std", "rayon", "ark-std/parallel", "ark-serialize/parallel"]
asm = []
allocative = ["dep:allocative"]
31 changes: 31 additions & 0 deletions ff/src/biginteger/arithmetic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,37 @@ pub fn mac_discard(a: u64, b: u64, c: u64, carry: &mut u64) {
*carry = (tmp >> 64) as u64;
}

/// Accumulate `limbs` into an N-limb accumulator starting at `lane_offset` (64-bit lanes),
/// returning the final carry. This is a helper for building wide accumulators.
#[inline(always)]
pub fn add_limbs_shifted_inplace<const N: usize>(
acc: &mut [u64; N],
limbs: &[u64],
lane_offset: usize,
) -> u64 {
let mut carry = 0u64;
let mut i = 0usize;
while i < limbs.len() {
let idx = lane_offset + i;
if idx >= N {
break;
}
let tmp = (acc[idx] as u128) + (limbs[i] as u128) + (carry as u128);
acc[idx] = tmp as u64;
carry = (tmp >> 64) as u64;
i += 1;
}
// propagate carry across remaining lanes if any
let mut idx = lane_offset + i;
while carry != 0 && idx < N {
let tmp = (acc[idx] as u128) + (carry as u128);
acc[idx] = tmp as u64;
carry = (tmp >> 64) as u64;
idx += 1;
}
carry
}

macro_rules! mac_with_carry {
($a:expr, $b:expr, $c:expr, &mut $carry:expr$(,)?) => {{
let tmp =
Expand Down
Loading
Loading