mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-08 12:19:24 +00:00
Correct decoding identity for embedwards25519/secq256k1
This commit is contained in:
@@ -7,7 +7,7 @@ This curve was found via
|
|||||||
for finding curves (specifically, curve cycles), modified to search for curves
|
for finding curves (specifically, curve cycles), modified to search for curves
|
||||||
whose field is the Ed25519 scalar field (not the Ed25519 field).
|
whose field is the Ed25519 scalar field (not the Ed25519 field).
|
||||||
|
|
||||||
```
|
```ignore
|
||||||
p = 0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed
|
p = 0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed
|
||||||
q = 0x0fffffffffffffffffffffffffffffffe53f4debb78ff96877063f0306eef96b
|
q = 0x0fffffffffffffffffffffffffffffffe53f4debb78ff96877063f0306eef96b
|
||||||
D = -420435
|
D = -420435
|
||||||
|
|||||||
@@ -198,6 +198,7 @@ impl Group for Point {
|
|||||||
Point { x: FieldElement::ZERO, y: FieldElement::ONE, z: FieldElement::ZERO }
|
Point { x: FieldElement::ZERO, y: FieldElement::ONE, z: FieldElement::ZERO }
|
||||||
}
|
}
|
||||||
fn generator() -> Self {
|
fn generator() -> Self {
|
||||||
|
// Point with the lowest valid x-coordinate
|
||||||
Point {
|
Point {
|
||||||
x: FieldElement::from_repr(hex_literal::hex!(
|
x: FieldElement::from_repr(hex_literal::hex!(
|
||||||
"0100000000000000000000000000000000000000000000000000000000000000"
|
"0100000000000000000000000000000000000000000000000000000000000000"
|
||||||
@@ -335,8 +336,10 @@ impl GroupEncoding for Point {
|
|||||||
// If this the identity, set y to 1
|
// If this the identity, set y to 1
|
||||||
let y =
|
let y =
|
||||||
CtOption::conditional_select(&y, &CtOption::new(FieldElement::ONE, 1.into()), is_identity);
|
CtOption::conditional_select(&y, &CtOption::new(FieldElement::ONE, 1.into()), is_identity);
|
||||||
|
// If this the identity, set y to 1 and z to 0 (instead of 1)
|
||||||
|
let z = <_>::conditional_select(&FieldElement::ONE, &FieldElement::ZERO, is_identity);
|
||||||
// Create the point if we have a y solution
|
// Create the point if we have a y solution
|
||||||
let point = y.map(|y| Point { x, y, z: FieldElement::ONE });
|
let point = y.map(|y| Point { x, y, z });
|
||||||
|
|
||||||
let not_negative_zero = !(is_identity & sign);
|
let not_negative_zero = !(is_identity & sign);
|
||||||
// Only return the point if it isn't -0
|
// Only return the point if it isn't -0
|
||||||
|
|||||||
@@ -192,6 +192,7 @@ impl Group for Point {
|
|||||||
Point { x: FieldElement::ZERO, y: FieldElement::ONE, z: FieldElement::ZERO }
|
Point { x: FieldElement::ZERO, y: FieldElement::ONE, z: FieldElement::ZERO }
|
||||||
}
|
}
|
||||||
fn generator() -> Self {
|
fn generator() -> Self {
|
||||||
|
// Point with the lowest valid x-coordinate
|
||||||
Point {
|
Point {
|
||||||
x: FieldElement::from_repr(
|
x: FieldElement::from_repr(
|
||||||
hex_literal::hex!("0000000000000000000000000000000000000000000000000000000000000001")
|
hex_literal::hex!("0000000000000000000000000000000000000000000000000000000000000001")
|
||||||
@@ -334,8 +335,10 @@ impl GroupEncoding for Point {
|
|||||||
// If this the identity, set y to 1
|
// If this the identity, set y to 1
|
||||||
let y =
|
let y =
|
||||||
CtOption::conditional_select(&y, &CtOption::new(FieldElement::ONE, 1.into()), is_identity);
|
CtOption::conditional_select(&y, &CtOption::new(FieldElement::ONE, 1.into()), is_identity);
|
||||||
|
// If this the identity, set y to 1 and z to 0 (instead of 1)
|
||||||
|
let z = <_>::conditional_select(&FieldElement::ONE, &FieldElement::ZERO, is_identity);
|
||||||
// Create the point if we have a y solution
|
// Create the point if we have a y solution
|
||||||
let point = y.map(|y| Point { x, y, z: FieldElement::ONE });
|
let point = y.map(|y| Point { x, y, z });
|
||||||
|
|
||||||
let not_negative_zero = !(is_identity & sign);
|
let not_negative_zero = !(is_identity & sign);
|
||||||
// Only return the point if it isn't -0 and the sign byte wasn't malleated
|
// Only return the point if it isn't -0 and the sign byte wasn't malleated
|
||||||
|
|||||||
@@ -154,18 +154,20 @@ pub fn test_group<R: RngCore, G: Group>(rng: &mut R) {
|
|||||||
|
|
||||||
/// Test encoding and decoding of group elements.
|
/// Test encoding and decoding of group elements.
|
||||||
pub fn test_encoding<G: PrimeGroup>() {
|
pub fn test_encoding<G: PrimeGroup>() {
|
||||||
let test = |point: G, msg| {
|
let test = |point: G, msg| -> G {
|
||||||
let bytes = point.to_bytes();
|
let bytes = point.to_bytes();
|
||||||
let mut repr = G::Repr::default();
|
let mut repr = G::Repr::default();
|
||||||
repr.as_mut().copy_from_slice(bytes.as_ref());
|
repr.as_mut().copy_from_slice(bytes.as_ref());
|
||||||
assert_eq!(point, G::from_bytes(&repr).unwrap(), "{msg} couldn't be encoded and decoded");
|
let decoded = G::from_bytes(&repr).unwrap();
|
||||||
|
assert_eq!(point, decoded, "{msg} couldn't be encoded and decoded");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
point,
|
point,
|
||||||
G::from_bytes_unchecked(&repr).unwrap(),
|
G::from_bytes_unchecked(&repr).unwrap(),
|
||||||
"{msg} couldn't be encoded and decoded",
|
"{msg} couldn't be encoded and decoded",
|
||||||
);
|
);
|
||||||
|
decoded
|
||||||
};
|
};
|
||||||
test(G::identity(), "identity");
|
assert!(bool::from(test(G::identity(), "identity").is_identity()));
|
||||||
test(G::generator(), "generator");
|
test(G::generator(), "generator");
|
||||||
test(G::generator() + G::generator(), "(generator * 2)");
|
test(G::generator() + G::generator(), "(generator * 2)");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user