mirror of
https://github.com/saymrwulf/risc0-curve25519-dalek-source.git
synced 2026-09-04 20:03:40 +00:00
Add iterator length checks to multiscalar muls.
This partially re-adds functionality removed in commit
d2ce1ce5dc
We would like to require ExactSizeIterator, but unfortunately we can't
do that, since ExactSizeIterators aren't chainable, for (in my opinion)
silly reasons (chaining two 4-billion-element ExactSizeIterators could
overflow on 32-bit systems). Instead we inspect the size hints manually
and assert that the lower and upper bounds are all equal.
This commit is contained in:
parent
82a5e18c29
commit
b7dab8d083
1 changed files with 40 additions and 20 deletions
|
|
@ -556,21 +556,31 @@ impl MultiscalarMul for EdwardsPoint {
|
|||
J: IntoIterator,
|
||||
J::Item: Borrow<EdwardsPoint>,
|
||||
{
|
||||
// XXX later when we do more fancy multiscalar mults, we can
|
||||
// delegate based on the iter's size hint -- hdevalence
|
||||
// Sanity-check lengths of input iterators
|
||||
let mut scalars = scalars.into_iter();
|
||||
let mut points = points.into_iter();
|
||||
|
||||
// Lower and upper bounds on iterators
|
||||
let (s_lo, s_hi) = scalars.by_ref().size_hint();
|
||||
let (p_lo, p_hi) = points.by_ref().size_hint();
|
||||
|
||||
// They should all be equal
|
||||
assert_eq!(s_lo, p_lo);
|
||||
assert_eq!(s_hi, Some(s_lo));
|
||||
assert_eq!(p_hi, Some(p_lo));
|
||||
|
||||
// Now we know there's a single size. When we do
|
||||
// size-dependent algorithm dispatch, use this as the hint.
|
||||
let _size = s_lo;
|
||||
|
||||
// If we built with AVX2, use the AVX2 backend.
|
||||
#[cfg(all(feature="avx2_backend", target_feature="avx2"))]
|
||||
{
|
||||
use backend::avx2::scalar_mul::straus::Straus;
|
||||
Straus::multiscalar_mul(scalars, points)
|
||||
}
|
||||
use backend::avx2::scalar_mul::straus::Straus;
|
||||
// Otherwise, proceed as normal:
|
||||
#[cfg(not(all(feature="avx2_backend", target_feature="avx2")))]
|
||||
{
|
||||
use scalar_mul::straus::Straus;
|
||||
Straus::multiscalar_mul(scalars, points)
|
||||
}
|
||||
use scalar_mul::straus::Straus;
|
||||
|
||||
Straus::multiscalar_mul(scalars, points)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -584,21 +594,31 @@ impl VartimeMultiscalarMul for EdwardsPoint {
|
|||
I::Item: Borrow<Scalar>,
|
||||
J: IntoIterator<Item = Option<EdwardsPoint>>,
|
||||
{
|
||||
// XXX later when we do more fancy multiscalar mults, we can
|
||||
// delegate based on the iter's size hint -- hdevalence
|
||||
// Sanity-check lengths of input iterators
|
||||
let mut scalars = scalars.into_iter();
|
||||
let mut points = points.into_iter();
|
||||
|
||||
// Lower and upper bounds on iterators
|
||||
let (s_lo, s_hi) = scalars.by_ref().size_hint();
|
||||
let (p_lo, p_hi) = points.by_ref().size_hint();
|
||||
|
||||
// They should all be equal
|
||||
assert_eq!(s_lo, p_lo);
|
||||
assert_eq!(s_hi, Some(s_lo));
|
||||
assert_eq!(p_hi, Some(p_lo));
|
||||
|
||||
// Now we know there's a single size. When we do
|
||||
// size-dependent algorithm dispatch, use this as the hint.
|
||||
let _size = s_lo;
|
||||
|
||||
// If we built with AVX2, use the AVX2 backend.
|
||||
#[cfg(all(feature="avx2_backend", target_feature="avx2"))]
|
||||
{
|
||||
use backend::avx2::scalar_mul::straus::Straus;
|
||||
Straus::optional_multiscalar_mul(scalars, points)
|
||||
}
|
||||
use backend::avx2::scalar_mul::straus::Straus;
|
||||
// Otherwise, proceed as normal:
|
||||
#[cfg(not(all(feature="avx2_backend", target_feature="avx2")))]
|
||||
{
|
||||
use scalar_mul::straus::Straus;
|
||||
Straus::optional_multiscalar_mul(scalars, points)
|
||||
}
|
||||
use scalar_mul::straus::Straus;
|
||||
|
||||
Straus::optional_multiscalar_mul(scalars, points)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue