mirror of
https://github.com/saymrwulf/curve25519-dalek-source.git
synced 2026-09-06 20:41:14 +00:00
Made Scalar::bits return an iterator rather than an array (#451)
Addresses issue #448 that Scalar::bits may leave unzeroed bits on the stack
This commit is contained in:
parent
42e93d7faf
commit
0b72bb5dc2
2 changed files with 19 additions and 15 deletions
|
|
@ -335,17 +335,23 @@ impl<'a, 'b> Mul<&'b Scalar> for &'a MontgomeryPoint {
|
||||||
W: FieldElement::one(),
|
W: FieldElement::one(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let bits: [i8; 256] = scalar.bits();
|
// Go through the bits from most to least significant, using a sliding window of 2
|
||||||
|
let mut bits = scalar.bits_le().rev();
|
||||||
for i in (0..255).rev() {
|
let mut prev_bit = bits.next().unwrap();
|
||||||
let choice: u8 = (bits[i + 1] ^ bits[i]) as u8;
|
for cur_bit in bits {
|
||||||
|
let choice: u8 = (prev_bit ^ cur_bit) as u8;
|
||||||
|
|
||||||
debug_assert!(choice == 0 || choice == 1);
|
debug_assert!(choice == 0 || choice == 1);
|
||||||
|
|
||||||
ProjectivePoint::conditional_swap(&mut x0, &mut x1, choice.into());
|
ProjectivePoint::conditional_swap(&mut x0, &mut x1, choice.into());
|
||||||
differential_add_and_double(&mut x0, &mut x1, &affine_u);
|
differential_add_and_double(&mut x0, &mut x1, &affine_u);
|
||||||
|
|
||||||
|
prev_bit = cur_bit;
|
||||||
}
|
}
|
||||||
ProjectivePoint::conditional_swap(&mut x0, &mut x1, Choice::from(bits[0] as u8));
|
// The final value of prev_bit above is scalar.bits()[0], i.e., the LSB of scalar
|
||||||
|
ProjectivePoint::conditional_swap(&mut x0, &mut x1, Choice::from(prev_bit as u8));
|
||||||
|
// Don't leave the bit in the stack
|
||||||
|
prev_bit.zeroize();
|
||||||
|
|
||||||
x0.as_affine()
|
x0.as_affine()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -847,16 +847,14 @@ impl Scalar {
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the bits of the scalar.
|
/// Get the bits of the scalar, in little-endian order
|
||||||
pub(crate) fn bits(&self) -> [i8; 256] {
|
pub(crate) fn bits_le(&self) -> impl DoubleEndedIterator<Item = bool> + '_ {
|
||||||
let mut bits = [0i8; 256];
|
(0..256).map(|i| {
|
||||||
#[allow(clippy::needless_range_loop)]
|
// As i runs from 0..256, the bottom 3 bits index the bit, while the upper bits index
|
||||||
for i in 0..256 {
|
// the byte. Since self.bytes is little-endian at the byte level, this iterator is
|
||||||
// As i runs from 0..256, the bottom 3 bits index the bit,
|
// little-endian on the bit level
|
||||||
// while the upper bits index the byte.
|
((self.bytes[i >> 3] >> (i & 7)) & 1u8) == 1
|
||||||
bits[i] = ((self.bytes[i >> 3] >> (i & 7)) & 1u8) as i8;
|
})
|
||||||
}
|
|
||||||
bits
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compute a width-\\(w\\) "Non-Adjacent Form" of this scalar.
|
/// Compute a width-\\(w\\) "Non-Adjacent Form" of this scalar.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue