Skip to content

Commit c68840a

Browse files
committed
error handling done for inf values of sigs and vks and tests added
1 parent 62ae79e commit c68840a

File tree

2 files changed

+91
-16
lines changed

2 files changed

+91
-16
lines changed

mithril-stm/src/error.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,14 @@ pub enum MultiSignatureError {
2929
/// At least one signature in the batch is invalid
3030
#[error("One signature in the batch is invalid")]
3131
BatchInvalid,
32+
33+
/// Single signature is the infinity
34+
#[error("Single signature is the infinity")]
35+
SignatureInfinity(Signature),
36+
37+
/// Verification key is the infinity
38+
#[error("Verification key is the infinity")]
39+
VerificationKeyInfinity,
3240
}
3341

3442
/// Errors which can be output by Mithril single signature verification.
@@ -159,6 +167,8 @@ impl From<MultiSignatureError> for StmSignatureError {
159167
MultiSignatureError::BatchInvalid => unreachable!(),
160168
MultiSignatureError::KeyInvalid(_) => unreachable!(),
161169
MultiSignatureError::AggregateSignatureInvalid => unreachable!(),
170+
MultiSignatureError::SignatureInfinity(_) => unreachable!(),
171+
MultiSignatureError::VerificationKeyInfinity => unreachable!(),
162172
}
163173
}
164174
}
@@ -194,6 +204,12 @@ impl<D: Digest + FixedOutput> From<MultiSignatureError> for StmAggregateSignatur
194204
MultiSignatureError::SignatureInvalid(_) => {
195205
Self::CoreVerificationError(CoreVerifierError::from(e))
196206
}
207+
MultiSignatureError::SignatureInfinity(_) => {
208+
Self::CoreVerificationError(CoreVerifierError::from(e))
209+
}
210+
MultiSignatureError::VerificationKeyInfinity => {
211+
Self::CoreVerificationError(CoreVerifierError::from(e))
212+
}
197213
}
198214
}
199215
}
@@ -230,6 +246,8 @@ impl From<MultiSignatureError> for CoreVerifierError {
230246
MultiSignatureError::SerializationError => unreachable!(),
231247
MultiSignatureError::KeyInvalid(_) => unreachable!(),
232248
MultiSignatureError::SignatureInvalid(_e) => unreachable!(),
249+
MultiSignatureError::SignatureInfinity(_) => unreachable!(),
250+
MultiSignatureError::VerificationKeyInfinity => unreachable!(),
233251
}
234252
}
235253
}
@@ -258,6 +276,13 @@ pub(crate) fn blst_err_to_mithril(
258276
) -> Result<(), MultiSignatureError> {
259277
match e {
260278
BLST_ERROR::BLST_SUCCESS => Ok(()),
279+
BLST_ERROR::BLST_PK_IS_INFINITY => {
280+
if let Some(s) = sig {
281+
Err(MultiSignatureError::SignatureInfinity(s))
282+
} else {
283+
Err(MultiSignatureError::VerificationKeyInfinity)
284+
}
285+
}
261286
BLST_ERROR::BLST_VERIFY_FAIL => {
262287
if let Some(s) = sig {
263288
Err(MultiSignatureError::SignatureInvalid(s))

mithril-stm/src/multi_sig.rs

Lines changed: 66 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -196,15 +196,19 @@ impl VerificationKeyPoP {
196196
// If we are really looking for performance improvements, we can combine the
197197
// two final exponentiations (for verifying k1 and k2) into a single one.
198198
pub fn check(&self) -> Result<(), MultiSignatureError> {
199-
let result = verify_pairing(&self.vk, &self.pop);
200-
201-
if !(self.pop.k1.verify(false, POP, &[], &[], &self.vk.0, false)
202-
== BLST_ERROR::BLST_SUCCESS
203-
&& result)
204-
{
205-
return Err(MultiSignatureError::KeyInvalid(Box::new(*self)));
199+
match self.vk.0.validate() {
200+
Ok(_) => {
201+
let result = verify_pairing(&self.vk, &self.pop);
202+
if !(self.pop.k1.verify(false, POP, &[], &[], &self.vk.0, false)
203+
== BLST_ERROR::BLST_SUCCESS
204+
&& result)
205+
{
206+
return Err(MultiSignatureError::KeyInvalid(Box::new(*self)));
207+
}
208+
Ok(())
209+
}
210+
Err(e) => blst_err_to_mithril(e, None),
206211
}
207-
Ok(())
208212
}
209213

210214
/// Convert to a 144 byte string.
@@ -287,10 +291,13 @@ impl From<&SigningKey> for ProofOfPossession {
287291
impl Signature {
288292
/// Verify a signature against a verification key.
289293
pub fn verify(&self, msg: &[u8], mvk: &VerificationKey) -> Result<(), MultiSignatureError> {
290-
blst_err_to_mithril(
291-
self.0.verify(false, msg, &[], &[], &mvk.0, false),
292-
Some(*self),
293-
)
294+
match self.0.validate(true) {
295+
Ok(_) => blst_err_to_mithril(
296+
self.0.verify(false, msg, &[], &[], &mvk.0, false),
297+
Some(*self),
298+
),
299+
Err(e) => blst_err_to_mithril(e, Some(*self)),
300+
}
294301
}
295302

296303
/// Dense mapping function indexed by the index to be evaluated.
@@ -376,7 +383,6 @@ impl Signature {
376383
}
377384

378385
let transmuted_vks: Vec<blst_p2> = vks.iter().map(vk_from_p2_affine).collect();
379-
380386
let transmuted_sigs: Vec<blst_p1> = signatures.iter().map(sig_to_p1).collect();
381387

382388
let grouped_vks = p2_affines::from(transmuted_vks.as_slice());
@@ -628,6 +634,7 @@ mod unsafe_helpers {
628634
#[cfg(test)]
629635
mod tests {
630636
use super::*;
637+
use crate::key_reg::KeyReg;
631638
use proptest::prelude::*;
632639
use rand_chacha::ChaCha20Rng;
633640
use rand_core::{OsRng, SeedableRng};
@@ -647,9 +654,7 @@ mod tests {
647654
}
648655

649656
#[test]
650-
fn test_invalid_sig(msg in prop::collection::vec(any::<u8>(), 1..128),
651-
seed in any::<[u8;32]>(),
652-
) {
657+
fn test_invalid_sig(msg in prop::collection::vec(any::<u8>(), 1..128), seed in any::<[u8;32]>()) {
653658
let mut rng = ChaCha20Rng::from_seed(seed);
654659
let sk1 = SigningKey::gen(&mut rng);
655660
let vk1 = VerificationKey::from(&sk1);
@@ -658,6 +663,51 @@ mod tests {
658663
assert!(fake_sig.verify(&msg, &vk1).is_err());
659664
}
660665

666+
#[test]
667+
fn test_infinity_sig(msg in prop::collection::vec(any::<u8>(), 1..128), seed in any::<[u8;32]>()) {
668+
let mut rng = ChaCha20Rng::from_seed(seed);
669+
let sk = SigningKey::gen(&mut rng);
670+
let vk = VerificationKey::from(&sk);
671+
672+
let p1 = blst_p1::default();
673+
let sig_infinity = Signature(p1_affine_to_sig(&p1));
674+
675+
assert!(sig_infinity.verify(&msg, &vk).is_err());
676+
}
677+
678+
#[test]
679+
fn test_infinity_vk(seed in any::<[u8;32]>()) {
680+
let mut rng = ChaCha20Rng::from_seed(seed);
681+
let sk = SigningKey::gen(&mut rng);
682+
let pop = ProofOfPossession::from(&sk);
683+
684+
let p2 = blst_p2::default();
685+
let vk_infinity = VerificationKey(p2_affine_to_vk(&p2));
686+
let vkpop_infinity = VerificationKeyPoP { vk: vk_infinity, pop };
687+
688+
assert!(vkpop_infinity.check().is_err());
689+
}
690+
691+
#[test]
692+
fn test_keyreg_with_infinity_vk(num_sigs in 2..16usize, seed in any::<[u8;32]>()) {
693+
let mut rng = ChaCha20Rng::from_seed(seed);
694+
let mut kr = KeyReg::init();
695+
696+
let sk = SigningKey::gen(&mut rng);
697+
let pop = ProofOfPossession::from(&sk);
698+
let p2 = blst_p2::default();
699+
let vk_infinity = VerificationKey(p2_affine_to_vk(&p2));
700+
let vkpop_infinity = VerificationKeyPoP { vk: vk_infinity, pop };
701+
702+
for _ in 0..num_sigs {
703+
let sk = SigningKey::gen(&mut rng);
704+
let vkpop = VerificationKeyPoP::from(&sk);
705+
let _ = kr.register(1, vkpop);
706+
}
707+
708+
assert!(kr.register(1, vkpop_infinity).is_err());
709+
}
710+
661711
#[test]
662712
fn test_aggregate_sig(msg in prop::collection::vec(any::<u8>(), 1..128),
663713
num_sigs in 2..16,

0 commit comments

Comments
 (0)