Split out parsing & validation of test VerificationKey from checking of signature
Also use fully secure ChaChaRng with a full seed, not just a u64. Now that we always generate an extra proper VerificationKey for each Tweak::ChangePubkey case, this /should/ never fail: it also helps split out the actual verification of the signature from the parsing and validation of the key itself.
This commit is contained in:
parent
e2940a465d
commit
ad3d7fcd49
|
@ -0,0 +1,8 @@
|
|||
# Seeds for failure cases proptest has generated in the past. It is
|
||||
# automatically read and these particular cases re-run before any
|
||||
# novel cases are generated.
|
||||
#
|
||||
# It is recommended to check this file in to source control so that
|
||||
# everyone who runs the test benefits from these saved cases.
|
||||
cc 25716e9dc4549b01b395fca1fc076fc34300ad972ac59c5e098f7ec90a03446b # shrinks to tweaks = [ChangePubkey], rng_seed = 946433020594646748
|
||||
cc ddb674b23f131d33cdbe34f3959f7fc076f4815a12ad5d6f741ae38d2689d1c2 # shrinks to tweaks = [ChangePubkey, ChangePubkey, ChangePubkey, ChangePubkey], rng_seed = 8346595811973717667
|
|
@ -11,6 +11,7 @@ struct SignatureCase<T: SigType> {
|
|||
msg: Vec<u8>,
|
||||
sig: Signature<T>,
|
||||
pk_bytes: VerificationKeyBytes<T>,
|
||||
invalid_pk_bytes: VerificationKeyBytes<T>,
|
||||
is_valid: bool,
|
||||
}
|
||||
|
||||
|
@ -40,10 +41,12 @@ impl<T: SigType> SignatureCase<T> {
|
|||
let sk = SigningKey::new(&mut rng);
|
||||
let sig = sk.sign(&mut rng, &msg);
|
||||
let pk_bytes = VerificationKey::from(&sk).into();
|
||||
let invalid_pk_bytes = VerificationKey::from(&SigningKey::new(&mut rng)).into();
|
||||
Self {
|
||||
msg,
|
||||
sig,
|
||||
pk_bytes,
|
||||
invalid_pk_bytes,
|
||||
is_valid: true,
|
||||
}
|
||||
}
|
||||
|
@ -61,11 +64,12 @@ impl<T: SigType> SignatureCase<T> {
|
|||
VerificationKeyBytes::<T>::from(bytes)
|
||||
};
|
||||
|
||||
// Check that the verification key is a valid RedJubjub verification key.
|
||||
let pub_key = VerificationKey::try_from(pk_bytes)
|
||||
.expect("The test verification key to be well-formed.");
|
||||
|
||||
// Check that signature validation has the expected result.
|
||||
self.is_valid
|
||||
== VerificationKey::try_from(pk_bytes)
|
||||
.and_then(|pk| pk.verify(&self.msg, &sig))
|
||||
.is_ok()
|
||||
self.is_valid == pub_key.verify(&self.msg, &sig).is_ok()
|
||||
}
|
||||
|
||||
fn apply_tweak(&mut self, tweak: &Tweak) {
|
||||
|
@ -78,12 +82,7 @@ impl<T: SigType> SignatureCase<T> {
|
|||
}
|
||||
Tweak::ChangePubkey => {
|
||||
// Changing the public key makes the signature invalid.
|
||||
let mut bytes: [u8; 32] = self.pk_bytes.clone().into();
|
||||
let j = (bytes[2] & 31) as usize;
|
||||
bytes[2] ^= 0x23;
|
||||
bytes[2] |= 0x99;
|
||||
bytes[j] ^= bytes[2];
|
||||
self.pk_bytes = bytes.into();
|
||||
self.pk_bytes = self.invalid_pk_bytes;
|
||||
self.is_valid = false;
|
||||
}
|
||||
}
|
||||
|
@ -103,15 +102,15 @@ use rand_core::SeedableRng;
|
|||
|
||||
proptest! {
|
||||
|
||||
#[test]
|
||||
#[test]
|
||||
fn tweak_signature(
|
||||
tweaks in prop::collection::vec(tweak_strategy(), (0,5)),
|
||||
rng_seed in any::<u64>(),
|
||||
rng_seed in prop::array::uniform32(any::<u8>()),
|
||||
) {
|
||||
// Use a deterministic RNG so that test failures can be reproduced.
|
||||
// Seeding with 64 bits of entropy is INSECURE and this code should
|
||||
// not be copied outside of this test!
|
||||
let mut rng = ChaChaRng::seed_from_u64(rng_seed);
|
||||
let mut rng = ChaChaRng::from_seed(rng_seed);
|
||||
|
||||
// Create a test case for each signature type.
|
||||
let msg = b"test message for proptests";
|
||||
|
@ -129,11 +128,9 @@ proptest! {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn randomization_commutes_with_pubkey_homomorphism(rng_seed in any::<u64>()) {
|
||||
fn randomization_commutes_with_pubkey_homomorphism(rng_seed in prop::array::uniform32(any::<u8>())) {
|
||||
// Use a deterministic RNG so that test failures can be reproduced.
|
||||
// Seeding with 64 bits of entropy is INSECURE and this code should
|
||||
// not be copied outside of this test!
|
||||
let mut rng = ChaChaRng::seed_from_u64(rng_seed);
|
||||
let mut rng = ChaChaRng::from_seed(rng_seed);
|
||||
|
||||
let r = {
|
||||
// XXX-jubjub: better API for this
|
||||
|
|
Loading…
Reference in New Issue