Skip to content

Commit

Permalink
bindings/rust: add MultiScalar trait.
Browse files Browse the repository at this point in the history
This allows to perform multi-scalar operations directly on slices of
affine points without going through p{12}_affines classes.
  • Loading branch information
dot-asm committed May 27, 2024
1 parent 704c7f6 commit 86c30bc
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 14 deletions.
7 changes: 7 additions & 0 deletions bindings/rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1970,6 +1970,13 @@ pub mod min_sig {
);
}

pub trait MultiScalar {
type Output;

fn mult(&self, scalars: &[u8], nbits: usize) -> Self::Output;
fn add(&self) -> Self::Output;
}

#[cfg(feature = "std")]
include!("pippenger.rs");

Expand Down
23 changes: 17 additions & 6 deletions bindings/rust/src/pippenger-no_std.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,26 @@ macro_rules! pippenger_mult_impl {
}

pub fn mult(&self, scalars: &[u8], nbits: usize) -> $point {
let npoints = self.points.len();
self.as_slice().mult(scalars, nbits)
}

pub fn add(&self) -> $point {
self.as_slice().add()
}
}

impl MultiScalar for [$point_affine] {
type Output = $point;

fn mult(&self, scalars: &[u8], nbits: usize) -> $point {
let npoints = self.len();
let nbytes = (nbits + 7) / 8;

if scalars.len() < nbytes * npoints {
panic!("scalars length mismatch");
}

let p: [*const $point_affine; 2] =
[&self.points[0], ptr::null()];
let p: [*const $point_affine; 2] = [&self[0], ptr::null()];
let s: [*const u8; 2] = [&scalars[0], ptr::null()];

let mut ret = <$point>::default();
Expand All @@ -89,10 +100,10 @@ macro_rules! pippenger_mult_impl {
ret
}

pub fn add(&self) -> $point {
let npoints = self.points.len();
fn add(&self) -> $point {
let npoints = self.len();

let p: [*const _; 2] = [&self.points[0], ptr::null()];
let p: [*const _; 2] = [&self[0], ptr::null()];
let mut ret = <$point>::default();
unsafe { $add(&mut ret, &p[0], npoints) };

Expand Down
27 changes: 19 additions & 8 deletions bindings/rust/src/pippenger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,19 @@ macro_rules! pippenger_mult_impl {
}

pub fn mult(&self, scalars: &[u8], nbits: usize) -> $point {
let npoints = self.points.len();
self.as_slice().mult(scalars, nbits)
}

pub fn add(&self) -> $point {
self.as_slice().add()
}
}

impl MultiScalar for [$point_affine] {
type Output = $point;

fn mult(&self, scalars: &[u8], nbits: usize) -> $point {
let npoints = self.len();
let nbytes = (nbits + 7) / 8;

if scalars.len() < nbytes * npoints {
Expand All @@ -124,8 +136,7 @@ macro_rules! pippenger_mult_impl {
let pool = mt::da_pool();
let ncpus = pool.max_count();
if ncpus < 2 || npoints < 32 {
let p: [*const $point_affine; 2] =
[&self.points[0], ptr::null()];
let p: [*const $point_affine; 2] = [&self[0], ptr::null()];
let s: [*const u8; 2] = [&scalars[0], ptr::null()];

unsafe {
Expand Down Expand Up @@ -178,7 +189,7 @@ macro_rules! pippenger_mult_impl {
}
let grid = &grid[..];

let points = &self.points[..];
let points = &self[..];
let sz = unsafe { $scratch_sizeof(0) / 8 };

let mut row_sync: Vec<AtomicUsize> = Vec::with_capacity(ny);
Expand Down Expand Up @@ -262,13 +273,13 @@ macro_rules! pippenger_mult_impl {
ret
}

pub fn add(&self) -> $point {
let npoints = self.points.len();
fn add(&self) -> $point {
let npoints = self.len();

let pool = mt::da_pool();
let ncpus = pool.max_count();
if ncpus < 2 || npoints < 384 {
let p: [*const _; 2] = [&self.points[0], ptr::null()];
let p: [*const _; 2] = [&self[0], ptr::null()];
let mut ret = <$point>::default();
unsafe { $add(&mut ret, &p[0], npoints) };
return ret;
Expand All @@ -295,7 +306,7 @@ macro_rules! pippenger_mult_impl {
if work >= npoints {
break;
}
p[0] = &self.points[work];
p[0] = &self[work];
if work + chunk > npoints {
chunk = npoints - work;
}
Expand Down

0 comments on commit 86c30bc

Please sign in to comment.