Skip to content

Commit

Permalink
Fix check in signature verification
Browse files Browse the repository at this point in the history
Resolves #7
  • Loading branch information
moCello committed Feb 23, 2024
1 parent 0b5f3b0 commit 62469f1
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 1 deletion.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Change the implementation for hashing a slice of bytes into a BlsScalar to `BlsScalar::hash_to_scalar` [#3]

### Added

- Add `is_valid` check for `PublicKey` [#7]

## [0.1.0] - 2024-01-08

### Added

- 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
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

0 comments on commit 62469f1

Please sign in to comment.