mirror of
https://github.com/saymrwulf/curve25519-dalek-source.git
synced 2026-09-04 20:24:10 +00:00
Expose a Ristretto::from_uniform_bytes function.
Why expose this instead of `from_hash`? Because it allows constructing arbitrary-length chains of orthogonal generators from a XOF.
This commit is contained in:
parent
920bdb3279
commit
259e2cd188
1 changed files with 22 additions and 14 deletions
|
|
@ -576,19 +576,10 @@ impl RistrettoPoint {
|
|||
/// point should be unknown. The map is applied twice and the
|
||||
/// results are added, to ensure a uniform distribution.
|
||||
pub fn random<T: Rng + CryptoRng>(rng: &mut T) -> Self {
|
||||
let mut field_bytes = [0u8; 32];
|
||||
let mut uniform_bytes = [0u8; 64];
|
||||
rng.fill(&mut uniform_bytes);
|
||||
|
||||
rng.fill(&mut field_bytes);
|
||||
let r_1 = FieldElement::from_bytes(&field_bytes);
|
||||
let R_1 = RistrettoPoint::elligator_ristretto_flavor(&r_1);
|
||||
|
||||
rng.fill(&mut field_bytes);
|
||||
let r_2 = FieldElement::from_bytes(&field_bytes);
|
||||
let R_2 = RistrettoPoint::elligator_ristretto_flavor(&r_2);
|
||||
|
||||
// Applying Elligator twice and adding the results ensures a
|
||||
// uniform distribution.
|
||||
&R_1 + &R_2
|
||||
RistrettoPoint::from_uniform_bytes(&uniform_bytes)
|
||||
}
|
||||
|
||||
/// Hash a slice of bytes into a `RistrettoPoint`.
|
||||
|
|
@ -639,14 +630,31 @@ impl RistrettoPoint {
|
|||
{
|
||||
// dealing with generic arrays is clumsy, until const generics land
|
||||
let output = hash.result();
|
||||
let mut output_bytes = [0u8; 64];
|
||||
output_bytes.copy_from_slice(&output.as_slice());
|
||||
|
||||
RistrettoPoint::from_uniform_bytes(&output_bytes)
|
||||
}
|
||||
|
||||
/// Construct a `RistrettoPoint` from 64 bytes of data.
|
||||
///
|
||||
/// If the input bytes are uniformly distributed, the resulting
|
||||
/// point will be uniformly distributed over the group, and its
|
||||
/// discrete log with respect to other points should be unknown.
|
||||
///
|
||||
/// # Implementation
|
||||
///
|
||||
/// This function splits the input array into two 32-byte halves,
|
||||
/// takes the low 255 bits of each half mod p, applies the
|
||||
/// Ristretto-flavored Elligator map to each, and adds the results.
|
||||
pub fn from_uniform_bytes(bytes: &[u8; 64]) -> RistrettoPoint {
|
||||
let mut r_1_bytes = [0u8; 32];
|
||||
r_1_bytes.copy_from_slice(&output.as_slice()[0..32]);
|
||||
r_1_bytes.copy_from_slice(&bytes[0..32]);
|
||||
let r_1 = FieldElement::from_bytes(&r_1_bytes);
|
||||
let R_1 = RistrettoPoint::elligator_ristretto_flavor(&r_1);
|
||||
|
||||
let mut r_2_bytes = [0u8; 32];
|
||||
r_2_bytes.copy_from_slice(&output.as_slice()[32..64]);
|
||||
r_2_bytes.copy_from_slice(&bytes[32..64]);
|
||||
let r_2 = FieldElement::from_bytes(&r_2_bytes);
|
||||
let R_2 = RistrettoPoint::elligator_ristretto_flavor(&r_2);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue