Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 63 additions & 1 deletion ec/src/models/short_weierstrass/affine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@
if x.is_zero() && flags.is_infinity() {
Some(Self::identity())
} else if let Some(y_is_positive) = flags.is_positive() {
Self::get_point_from_x_unchecked(x, y_is_positive)
Self::get_point_from_x_unchecked(x, !y_is_positive)
// Unwrap is safe because it's not zero.
} else {
None
Expand Down Expand Up @@ -444,3 +444,65 @@
Some(x)
}
}

#[cfg(test)]
mod tests {
use super::*;
use ark_serialize::CanonicalSerialize;

Check failure on line 451 in ec/src/models/short_weierstrass/affine.rs

View workflow job for this annotation

GitHub Actions / Test (nightly)

unused import: `ark_serialize::CanonicalSerialize`

Check warning on line 451 in ec/src/models/short_weierstrass/affine.rs

View workflow job for this annotation

GitHub Actions / Test assembly

unused import: `ark_serialize::CanonicalSerialize`
use ark_std::test_rng;

// Use a concrete SW curve from ark-test-curves for interoperability tests.
use ark_test_curves::bls12_381::{g1::Config as G1Config, Fq};

type G1Affine = Affine<G1Config>;

#[test]
fn from_random_bytes_respects_swflags_semantics() {
let mut rng = test_rng();

// Pick random x that yields a valid point (non-None sqrt)
let x = loop {
let cand = Fq::rand(&mut rng);
if G1Affine::get_ys_from_x_unchecked(cand).is_some() {

Check failure on line 466 in ec/src/models/short_weierstrass/affine.rs

View workflow job for this annotation

GitHub Actions / Test (nightly)

the function or associated item `get_ys_from_x_unchecked` exists for struct `models::short_weierstrass::affine::Affine<ark_test_curves::bls12_381::g1::Config>`, but its trait bounds were not satisfied

Check failure on line 466 in ec/src/models/short_weierstrass/affine.rs

View workflow job for this annotation

GitHub Actions / Test (nightly)

the trait bound `ark_test_curves::bls12_381::g1::Config: models::short_weierstrass::SWCurveConfig` is not satisfied

Check failure on line 466 in ec/src/models/short_weierstrass/affine.rs

View workflow job for this annotation

GitHub Actions / Test assembly

the function or associated item `get_ys_from_x_unchecked` exists for struct `models::short_weierstrass::affine::Affine<ark_test_curves::bls12_381::g1::Config>`, but its trait bounds were not satisfied

Check failure on line 466 in ec/src/models/short_weierstrass/affine.rs

View workflow job for this annotation

GitHub Actions / Test assembly

the trait bound `ark_test_curves::bls12_381::g1::Config: models::short_weierstrass::SWCurveConfig` is not satisfied
break cand;
}
};

let (y_small, y_large) = G1Affine::get_ys_from_x_unchecked(x).unwrap();

Check failure on line 471 in ec/src/models/short_weierstrass/affine.rs

View workflow job for this annotation

GitHub Actions / Test (nightly)

the function or associated item `get_ys_from_x_unchecked` exists for struct `models::short_weierstrass::affine::Affine<ark_test_curves::bls12_381::g1::Config>`, but its trait bounds were not satisfied

Check failure on line 471 in ec/src/models/short_weierstrass/affine.rs

View workflow job for this annotation

GitHub Actions / Test (nightly)

the trait bound `ark_test_curves::bls12_381::g1::Config: models::short_weierstrass::SWCurveConfig` is not satisfied

Check failure on line 471 in ec/src/models/short_weierstrass/affine.rs

View workflow job for this annotation

GitHub Actions / Test assembly

the function or associated item `get_ys_from_x_unchecked` exists for struct `models::short_weierstrass::affine::Affine<ark_test_curves::bls12_381::g1::Config>`, but its trait bounds were not satisfied

Check failure on line 471 in ec/src/models/short_weierstrass/affine.rs

View workflow job for this annotation

GitHub Actions / Test assembly

the trait bound `ark_test_curves::bls12_381::g1::Config: models::short_weierstrass::SWCurveConfig` is not satisfied

// Serialize x with explicit flags
let mut bytes_pos = Vec::new();
let mut bytes_neg = Vec::new();
x.serialize_with_flags(&mut bytes_pos, SWFlags::YIsPositive)

Check failure on line 476 in ec/src/models/short_weierstrass/affine.rs

View workflow job for this annotation

GitHub Actions / Test (nightly)

no method named `serialize_with_flags` found for struct `ark_ff::Fp<P, N>` in the current scope

Check failure on line 476 in ec/src/models/short_weierstrass/affine.rs

View workflow job for this annotation

GitHub Actions / Test assembly

no method named `serialize_with_flags` found for struct `ark_ff::Fp<P, N>` in the current scope
.unwrap();
x.serialize_with_flags(&mut bytes_neg, SWFlags::YIsNegative)

Check failure on line 478 in ec/src/models/short_weierstrass/affine.rs

View workflow job for this annotation

GitHub Actions / Test (nightly)

no method named `serialize_with_flags` found for struct `ark_ff::Fp<P, N>` in the current scope

Check failure on line 478 in ec/src/models/short_weierstrass/affine.rs

View workflow job for this annotation

GitHub Actions / Test assembly

no method named `serialize_with_flags` found for struct `ark_ff::Fp<P, N>` in the current scope
.unwrap();

// Decode via from_random_bytes and assert mapping to smaller/larger y
let p_pos =
G1Affine::from_random_bytes(&bytes_pos).expect("valid point with positive flag");

Check failure on line 483 in ec/src/models/short_weierstrass/affine.rs

View workflow job for this annotation

GitHub Actions / Test (nightly)

the function or associated item `from_random_bytes` exists for struct `models::short_weierstrass::affine::Affine<ark_test_curves::bls12_381::g1::Config>`, but its trait bounds were not satisfied

Check failure on line 483 in ec/src/models/short_weierstrass/affine.rs

View workflow job for this annotation

GitHub Actions / Test (nightly)

the trait bound `ark_test_curves::bls12_381::g1::Config: models::short_weierstrass::SWCurveConfig` is not satisfied

Check failure on line 483 in ec/src/models/short_weierstrass/affine.rs

View workflow job for this annotation

GitHub Actions / Test assembly

the function or associated item `from_random_bytes` exists for struct `models::short_weierstrass::affine::Affine<ark_test_curves::bls12_381::g1::Config>`, but its trait bounds were not satisfied

Check failure on line 483 in ec/src/models/short_weierstrass/affine.rs

View workflow job for this annotation

GitHub Actions / Test assembly

the trait bound `ark_test_curves::bls12_381::g1::Config: models::short_weierstrass::SWCurveConfig` is not satisfied
let p_neg =
G1Affine::from_random_bytes(&bytes_neg).expect("valid point with negative flag");

Check failure on line 485 in ec/src/models/short_weierstrass/affine.rs

View workflow job for this annotation

GitHub Actions / Test (nightly)

the trait bound `ark_test_curves::bls12_381::g1::Config: models::short_weierstrass::SWCurveConfig` is not satisfied

Check failure on line 485 in ec/src/models/short_weierstrass/affine.rs

View workflow job for this annotation

GitHub Actions / Test assembly

the function or associated item `from_random_bytes` exists for struct `models::short_weierstrass::affine::Affine<ark_test_curves::bls12_381::g1::Config>`, but its trait bounds were not satisfied

Check failure on line 485 in ec/src/models/short_weierstrass/affine.rs

View workflow job for this annotation

GitHub Actions / Test assembly

the trait bound `ark_test_curves::bls12_381::g1::Config: models::short_weierstrass::SWCurveConfig` is not satisfied

assert_eq!(p_pos.x, x);
assert_eq!(p_neg.x, x);
assert_eq!(
p_pos.y, y_small,
"YIsPositive must map to smaller y (y <= -y)"
);
assert_eq!(p_neg.y, y_large, "YIsNegative must map to larger y");
}

#[test]
fn from_random_bytes_handles_infinity_flag() {
// x = 0 with infinity flag should decode to identity
let x0 = Fq::ZERO;
let mut bytes_inf = Vec::new();
x0.serialize_with_flags(&mut bytes_inf, SWFlags::PointAtInfinity)
.unwrap();

let p =
G1Affine::from_random_bytes(&bytes_inf).expect("infinity must deserialize to identity");
assert!(p.is_zero());
}
}
Loading