From 0b5f3b0b2807036f4ff497fc163321a50a836b36 Mon Sep 17 00:00:00 2001 From: moana Date: Fri, 9 Feb 2024 17:32:11 +0100 Subject: [PATCH 1/2] Remove empty src/tests.rs file --- src/tests.rs | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 src/tests.rs diff --git a/src/tests.rs b/src/tests.rs deleted file mode 100644 index a30b949..0000000 --- a/src/tests.rs +++ /dev/null @@ -1,7 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. -// -// Copyright (c) DUSK NETWORK. All rights reserved. - -mod signature_test; From bc5e2815039ba828ddae9e0f9468ef7dbd29fae5 Mon Sep 17 00:00:00 2001 From: moana Date: Fri, 9 Feb 2024 17:51:26 +0100 Subject: [PATCH 2/2] Fix check in signature verification Resolves #7 --- CHANGELOG.md | 7 +++++++ src/error.rs | 5 +++++ src/keys/public.rs | 3 +++ src/signature.rs | 30 ++++++++++++++++++++++++++++++ tests/signature.rs | 14 +++++++++++++- 5 files changed, 58 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b611239..ea230ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 @@ -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. +[#7]: https://github.com/dusk-network/bls12_381-bls/issues/7 [#3]: https://github.com/dusk-network/bls12_381-bls/issues/3 diff --git a/src/error.rs b/src/error.rs index 7a4f79d..73bf55d 100644 --- a/src/error.rs +++ b/src/error.rs @@ -15,6 +15,8 @@ pub enum Error { BytesError(DuskBytesError), /// Cryptographic invalidity InvalidSignature, + /// Invalid Point + InvalidPoint, } impl From for Error { @@ -30,6 +32,9 @@ impl fmt::Display for Error { Self::InvalidSignature => { write!(f, "Invalid Signature") } + Self::InvalidPoint => { + write!(f, "Invalid Point") + } } } } diff --git a/src/keys/public.rs b/src/keys/public.rs index f7f6d84..36771af 100644 --- a/src/keys/public.rs +++ b/src/keys/public.rs @@ -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); diff --git a/src/signature.rs b/src/signature.rs index 8cb967d..93a4e23 100644 --- a/src/signature.rs +++ b/src/signature.rs @@ -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 { diff --git a/tests/signature.rs b/tests/signature.rs index cba191d..20420f4 100644 --- a/tests/signature.rs +++ b/tests/signature.rs @@ -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}; @@ -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];