Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add is_on_curve checks for affine and extended #138

Merged
merged 1 commit into from
Apr 24, 2024
Merged
Show file tree
Hide file tree
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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Add `Zeroize` trait for `JubJubScalar`, `JubJubAffine` and `JubJubExtended` [#135]
- Add `zeroize` optional dependency [#135]
- Add `is_on_curve` check for `JubJubAffine` and `JubJubExtended` [#137]

## [0.14.0] - 2023-12-13

Expand Down Expand Up @@ -219,6 +220,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Initial fork from [`zkcrypto/jubjub`]

<!-- ISSUES -->
[#137]: https://github.com/dusk-network/jubjub/issues/137
[#135]: https://github.com/dusk-network/jubjub/issues/135
[#129]: https://github.com/dusk-network/jubjub/issues/129
[#127]: https://github.com/dusk-network/jubjub/issues/127
Expand Down
59 changes: 58 additions & 1 deletion src/dusk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption};
pub use dusk_bls12_381::BlsScalar;
use dusk_bytes::{Error as BytesError, Serializable};

use crate::{Fr, JubJubAffine, JubJubExtended, EDWARDS_D};
use crate::{Fq, Fr, JubJubAffine, JubJubExtended, EDWARDS_D};

#[cfg(feature = "zeroize")]
impl zeroize::DefaultIsZeroes for JubJubAffine {}
Expand Down Expand Up @@ -161,6 +161,17 @@ impl Serializable<32> for JubJubAffine {
}
}

impl JubJubAffine {
/// Returns true if this point is on the curve. This should always return
/// true unless an "unchecked" API was used.
pub fn is_on_curve(&self) -> Choice {
// v^2 - u^2 - d * u^2 * v^2 ?= 1
let u2 = self.u.square();
let v2 = self.v.square();
(v2 - u2 - EDWARDS_D * u2 * v2).ct_eq(&Fq::one())
}
}

impl JubJubExtended {
/// Constructs an extended point (with `Z = 1`) from
/// an affine point using the map `(x, y) => (x, y, 1, x, y)`.
Expand Down Expand Up @@ -261,6 +272,18 @@ impl JubJubExtended {
counter += 1
}
}

/// Returns true if this point is on the curve. This should always return
/// true unless an "unchecked" API was used.
pub fn is_on_curve(&self) -> Choice {
let affine = JubJubAffine::from(*self);

(((self.z != Fq::zero())
&& affine.is_on_curve().into()
&& (affine.u * affine.v * self.z == self.t1 * self.t2))
as u8)
.into()
}
}

#[test]
Expand Down Expand Up @@ -302,6 +325,40 @@ fn test_affine_point_generator_nums_is_not_identity() {
);
}

#[test]
fn test_is_on_curve() {
assert!(bool::from(JubJubAffine::identity().is_on_curve()));
assert!(bool::from(GENERATOR.is_on_curve()));
assert!(bool::from(GENERATOR_NUMS.is_on_curve()));
assert!(bool::from(JubJubExtended::identity().is_on_curve()));
assert!(bool::from(GENERATOR_EXTENDED.is_on_curve()));
assert!(bool::from(GENERATOR_NUMS_EXTENDED.is_on_curve()));

let mut rng = rand_core::OsRng;
for _ in 0..1000 {
let affine = GENERATOR * &Fr::random(&mut rng);
assert!(bool::from(affine.is_on_curve()));

let extended = GENERATOR_EXTENDED * &Fr::random(&mut rng);
assert!(bool::from(extended.is_on_curve()));
}

let affine_invalid = JubJubAffine::from_raw_unchecked(
BlsScalar::from(42),
BlsScalar::from(42),
);
assert!(!bool::from(affine_invalid.is_on_curve()));

let extended_invalid = JubJubExtended::from_raw_unchecked(
BlsScalar::from(42),
BlsScalar::from(42),
BlsScalar::from(42),
BlsScalar::from(21),
BlsScalar::from(2),
);
assert!(!bool::from(extended_invalid.is_on_curve()));
}

#[test]
fn second_gen_nums() {
use blake2::{Blake2b, Digest};
Expand Down