avoid unnecessary allocation

This commit is contained in:
Oleg Andreev 2019-05-22 11:14:26 -07:00
parent df745e98a2
commit 7fba2a1bcc
2 changed files with 20 additions and 27 deletions

View file

@ -112,7 +112,7 @@ impl VartimeMultiscalarMul for Pippenger {
.map(|_| EdwardsPoint::identity())
.collect();
let columns: Vec<_> = (0..digits_count).map(|digit_index| {
let mut columns = (0..digits_count).rev().map(|digit_index| {
// Clear the buckets when processing another digit.
for i in 0..buckets_count {
@ -150,18 +150,17 @@ impl VartimeMultiscalarMul for Pippenger {
}
buckets_sum
})
.collect();
// ^ Note: we collect points because if we chain .rev().fold()
// then the .map() will run in reversed order, producing incorrect digit values
// (they can only be produced in lo->hi order).
});
// Add the intermediate per-digit results in hi->lo order
// so that we can minimize doublings.
Some(columns[0..(digits_count - 1)].iter().rev().fold(
columns[digits_count - 1],
|total, &p| total.mul_by_pow_2(w as u32) + p,
))
// Take the high column as an initial value to avoid wasting time doubling the identity element in `fold()`.
// `unwrap()` always succeeds because we know we have more than zero digits.
let hi_column = columns.next().unwrap();
Some(
columns.fold(hi_column, |total, p| {
total.mul_by_pow_2(w as u32) + p
}).into()
)
}
}

View file

@ -69,7 +69,7 @@ impl VartimeMultiscalarMul for Pippenger {
.map(|_| ExtendedPoint::identity())
.collect();
let columns: Vec<ExtendedPoint> = (0..digits_count).map(|digit_index| {
let mut columns = (0..digits_count).rev().map(|digit_index| {
// Clear the buckets when processing another digit.
for i in 0..buckets_count {
@ -107,22 +107,16 @@ impl VartimeMultiscalarMul for Pippenger {
}
buckets_sum
})
.collect();
// ^ Note: we collect points because if we chain .rev().fold()
// then the .map() will run in reversed order, producing incorrect digit values
// (they can only be produced in lo->hi order).
});
// Take the high column as an initial value to avoid wasting time doubling the identity element in `fold()`.
// `unwrap()` always succeeds because we know we have more than zero digits.
let hi_column = columns.next().unwrap();
// Add the intermediate per-digit results in hi->lo order
// so that we can minimize doublings.
Some(
columns[0..(digits_count - 1)]
.iter()
.rev()
.fold(columns[digits_count - 1], |total, &p| {
&total.mul_by_pow_2(w as u32) + &CachedPoint::from(p)
})
.into(),
columns.fold(hi_column, |total, p| {
&total.mul_by_pow_2(w as u32) + &CachedPoint::from(p)
}).into()
)
}
}