mirror of
https://github.com/saymrwulf/curve25519-dalek-source.git
synced 2026-09-08 21:00:40 +00:00
Rewrite CompressedEdwardsY::decompress() to use FieldElement::sqrt_ratio
This commit is contained in:
parent
1febf3f753
commit
d450659b7f
2 changed files with 20 additions and 41 deletions
49
src/curve.rs
49
src/curve.rs
|
|
@ -127,45 +127,24 @@ impl CompressedEdwardsY {
|
||||||
|
|
||||||
/// Attempt to decompress to an `ExtendedPoint`.
|
/// Attempt to decompress to an `ExtendedPoint`.
|
||||||
///
|
///
|
||||||
/// # Warning
|
/// Returns `None` if the input is not the `y`-coordinate of a
|
||||||
///
|
/// curve point.
|
||||||
/// This function will fail and return None if both vx²-u=0 and vx²+u=0.
|
|
||||||
pub fn decompress(&self) -> Option<ExtendedPoint> { // FromBytes()
|
pub fn decompress(&self) -> Option<ExtendedPoint> { // FromBytes()
|
||||||
let mut u: FieldElement;
|
let Y = FieldElement::from_bytes(&self.0);
|
||||||
let mut v: FieldElement;
|
let Z = FieldElement::one();
|
||||||
let v3: FieldElement;
|
let YY = Y.square();
|
||||||
let vxx: FieldElement;
|
let u = &YY - &Z; // u = y²-1
|
||||||
|
let v = &(&YY * &constants::d) + &Z; // v = dy²+1
|
||||||
|
let (is_nonzero_square, mut X) = FieldElement::sqrt_ratio(&u, &v);
|
||||||
|
|
||||||
let mut X: FieldElement;
|
if is_nonzero_square != 1u8 { return None; }
|
||||||
let Y: FieldElement;
|
|
||||||
let Z: FieldElement;
|
|
||||||
let T: FieldElement;
|
|
||||||
|
|
||||||
Y = FieldElement::from_bytes(&self.0);
|
// Flip the sign of X if it's not correct
|
||||||
Z = FieldElement::one();
|
let compressed_sign_bit = self[31] >> 7;
|
||||||
|
let current_sign_bit = X.is_negative_ed25519();
|
||||||
|
X.conditional_negate(current_sign_bit ^ compressed_sign_bit);
|
||||||
|
|
||||||
u = Y.square();
|
Some(ExtendedPoint{ X: X, Y: Y, Z: Z, T: &X * &Y })
|
||||||
v = &u * &constants::d;
|
|
||||||
u -= &Z; // u = y²-1
|
|
||||||
v += &Z; // v = dy²+1
|
|
||||||
v3 = &v.square() * &v; // v3 = v³
|
|
||||||
X = (&v3.square() * &(&v * &u)).pow_p58(); // x = (uv⁷)^((q-5)/8)
|
|
||||||
X *= &(&u * &v3); // x = (uv³)(uv⁷)^((q-5)/8)
|
|
||||||
|
|
||||||
vxx = &v * &X.square();
|
|
||||||
if (&vxx - &u).is_nonzero() == 1 { // vx²-u
|
|
||||||
if (&vxx + &u).is_nonzero() == 1 { // vx²+u
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
X *= &constants::SQRT_M1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if X.is_negative_ed25519() != (self[31] >> 7) as i32 {
|
|
||||||
X = X.neg();
|
|
||||||
}
|
|
||||||
T = &X * &Y;
|
|
||||||
|
|
||||||
Some(ExtendedPoint{ X: X, Y: Y, Z: Z, T: T })
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
12
src/field.rs
12
src/field.rs
|
|
@ -517,16 +517,16 @@ impl FieldElement {
|
||||||
(!equal_so_far & 1 & greater) as u8
|
(!equal_so_far & 1 & greater) as u8
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Determine if this `FieldElement` is negative, in the
|
/// Determine if this `FieldElement` is negative, in the sense
|
||||||
/// sense used in the ed25519 paper.
|
/// used in the ed25519 paper: `x` is negative if the low bit is
|
||||||
|
/// set.
|
||||||
///
|
///
|
||||||
/// # Return
|
/// # Return
|
||||||
///
|
///
|
||||||
/// If negative, return `1i32`. Otherwise, return `0i32`.
|
/// If negative, return `1u8`. Otherwise, return `0u8`.
|
||||||
// XXX should return u8
|
pub fn is_negative_ed25519(&self) -> u8 { //FeIsNegative
|
||||||
pub fn is_negative_ed25519(&self) -> i32 { //FeIsNegative
|
|
||||||
let bytes = self.to_bytes();
|
let bytes = self.to_bytes();
|
||||||
(bytes[0] & 1) as i32
|
(bytes[0] & 1) as u8
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Determine if this `FieldElement` is negative, in the
|
/// Determine if this `FieldElement` is negative, in the
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue