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

Fix check in signature verification #9

Merged
merged 2 commits into from
Apr 17, 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
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed

- Change the implementation for hashing a slice of bytes into a BlsScalar to `BlsScalar::hash_to_scalar` [#3]
- Check validity of `PublicKey` and `Signature` points in signature verification [#7]

### Added

- Add `is_valid` check for `PublicKey` [#7]
- Add `Error::InvalidPoint` variant for invalid `PublicKey` and `Signature` points [#7]

## [0.1.0] - 2024-01-08

Expand All @@ -18,6 +24,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Add initial commit, this package continues the development of [dusk-bls12_381-sign](https://github.com/dusk-network/bls12_381-sign/) at version `0.6.0` under the new name: `bls12_381-bls` and without the go related code.

<!-- ISSUES -->
[#7]: https://github.com/dusk-network/bls12_381-bls/issues/7
[#3]: https://github.com/dusk-network/bls12_381-bls/issues/3

<!-- VERSIONS -->
Expand Down
5 changes: 5 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ pub enum Error {
BytesError(DuskBytesError),
/// Cryptographic invalidity
InvalidSignature,
/// Invalid Point
InvalidPoint,
}

impl From<DuskBytesError> for Error {
Expand All @@ -30,6 +32,9 @@ impl fmt::Display for Error {
Self::InvalidSignature => {
write!(f, "Invalid Signature")
}
Self::InvalidPoint => {
write!(f, "Invalid Point")
}
}
}
}
3 changes: 3 additions & 0 deletions src/keys/public.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ impl PublicKey {
/// Verify a [`Signature`] by comparing the results of the two pairing
/// operations: e(sig, g_2) == e(Hₒ(m), pk).
pub fn verify(&self, sig: &Signature, msg: &[u8]) -> Result<(), Error> {
if !self.is_valid() || !sig.is_valid() {
return Err(Error::InvalidPoint);
}
let h0m = h0(msg);
let p1 = dusk_bls12_381::pairing(&sig.0, &G2Affine::generator());
let p2 = dusk_bls12_381::pairing(&h0m, &self.0);
Expand Down
30 changes: 30 additions & 0 deletions src/signature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,36 @@ impl Signature {
}),
)
}

/// Returns true if the inner point is free of an $h$-torsion component, and
/// so it exists within the $q$-order subgroup $\mathbb{G}_2$. This
/// should always return true unless an "unchecked" API was used.
pub fn is_torsion_free(&self) -> bool {
self.0.is_torsion_free().into()
}

/// Returns true if the inner point is on the curve. This should always
/// return true unless an "unchecked" API was used.
pub fn is_on_curve(&self) -> bool {
self.0.is_on_curve().into()
}

/// Returns true if the inner point is the identity (the point at infinity).
pub fn is_identity(&self) -> bool {
self.0.is_identity().into()
}

/// Returns true if the inner point is valid according to certain criteria.
///
/// A [`Signature`] is considered valid if its inner point meets the
/// following conditions:
/// 1. It is free of an $h$-torsion component and exists within the
/// $q$-order subgroup $\mathbb{G}_2$.
/// 2. It is on the curve.
/// 3. It is not the identity.
pub fn is_valid(&self) -> bool {
self.is_torsion_free() && self.is_on_curve() && !self.is_identity()
}
}

impl Serializable<48> for Signature {
Expand Down
7 changes: 0 additions & 7 deletions src/tests.rs

This file was deleted.

14 changes: 13 additions & 1 deletion tests/signature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
//
// Copyright (c) DUSK NETWORK. All rights reserved.

use bls12_381_bls::{PublicKey, SecretKey, APK};
use bls12_381_bls::{Error, PublicKey, SecretKey, APK};
use dusk_bls12_381::BlsScalar;
use rand::rngs::StdRng;
use rand::{RngCore, SeedableRng};

Expand Down Expand Up @@ -178,6 +179,17 @@ fn sign_verify_aggregated_incorrect_apk() {
assert!(apk.verify(&agg_sig, &msg).is_err());
}

#[test]
fn sign_verify_identity_fails() {
let rng = &mut StdRng::seed_from_u64(0xbeef);
let msg = random_message(rng);
let sk = SecretKey::from(BlsScalar::zero());
let pk = PublicKey::from(&sk);
let sig = sk.sign_vulnerable(&msg);

assert_eq!(pk.verify(&sig, &msg).unwrap_err(), Error::InvalidPoint);
}

fn random_message(rng: &mut StdRng) -> [u8; 100] {
let mut msg = [0u8; 100];

Expand Down