Skip to content

Commit

Permalink
Attempt to use Intoiterator to abstract over collection types, does n…
Browse files Browse the repository at this point in the history
…ot work.
  • Loading branch information
burdges committed Jul 31, 2018
1 parent a3bbece commit 6b53813
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 7 deletions.
13 changes: 8 additions & 5 deletions src/bls12_381/ec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -334,28 +334,31 @@ macro_rules! curve_impl {
self.is_zero() || self.z == $basefield::one()
}

fn batch_normalization(v: &mut [Self])
fn batch_normalization<II: ?Sized>(v: &mut II)
where for<'a> &'a mut II: IntoIterator<Item = &'a mut Self>,
for<'a> <&'a mut II as IntoIterator>::IntoIter: DoubleEndedIterator+ExactSizeIterator
{
// Montgomery’s Trick and Fast Implementation of Masked AES
// Genelle, Prouff and Quisquater
// Section 3.2

// First pass: compute [a, ab, abc, ...]
let mut prod = Vec::with_capacity(v.len());
let mut prod = Vec::with_capacity(v.into_iter().len());
let mut tmp = $basefield::one();
for g in v.iter_mut()
for g in v.into_iter()
// Ignore normalized elements
.filter(|g| !g.is_normalized())
{
tmp.mul_assign(&g.z);
prod.push(tmp);
}
if prod.is_empty() { return; }

// Invert `tmp`.
tmp = tmp.inverse().unwrap(); // Guaranteed to be nonzero.

// Second pass: iterate backwards to compute inverses
for (g, s) in v.iter_mut()
for (g, s) in v.into_iter()
// Backwards
.rev()
// Ignore normalized elements
Expand All @@ -372,7 +375,7 @@ macro_rules! curve_impl {
}

// Perform affine transformations
for g in v.iter_mut()
for g in v.into_iter()
.filter(|g| !g.is_normalized())
{
let mut z = g.z; // 1/z
Expand Down
5 changes: 4 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,10 @@ pub trait CurveProjective:

/// Normalizes a slice of projective elements so that
/// conversion to affine is cheap.
fn batch_normalization(v: &mut [Self]);
fn batch_normalization<II: ?Sized>(v: &mut II)
where for<'a> &'a mut II: IntoIterator<Item = &'a mut Self>,
for<'a> <&'a mut II as IntoIterator>::IntoIter: DoubleEndedIterator+ExactSizeIterator;
// TODO: Simplify using https://github.com/rust-lang/rfcs/pull/2289

/// Checks if the point is already "normalized" so that
/// cheap affine conversion is possible.
Expand Down
2 changes: 1 addition & 1 deletion src/tests/curve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,7 @@ fn random_transformation_tests<G: CurveProjective>() {
let expected_v = v.iter()
.map(|v| v.into_affine().into_projective())
.collect::<Vec<_>>();
G::batch_normalization(&mut v);
G::batch_normalization(v.as_mut_slice());

for i in &v {
assert!(i.is_normalized());
Expand Down

0 comments on commit 6b53813

Please sign in to comment.