Test invalid decryption edge cases

This commit is contained in:
Jack Grigg 2019-03-23 23:22:52 +13:00
parent 9086dd9afb
commit e17e4b1346
No known key found for this signature in database
GPG Key ID: 9E8255172BBF9898
1 changed files with 282 additions and 1 deletions

View File

@ -466,17 +466,20 @@ pub fn try_sapling_output_recovery(
mod tests {
use ff::{PrimeField, PrimeFieldRepr};
use pairing::bls12_381::{Bls12, Fr, FrRepr};
use rand::{thread_rng, Rand, Rng};
use sapling_crypto::{
jubjub::{
edwards,
fs::{Fs, FsRepr},
PrimeOrder, Unknown,
},
primitives::{Diversifier, PaymentAddress},
primitives::{Diversifier, PaymentAddress, ValueCommitment},
};
use super::{
kdf_sapling, prf_ock, sapling_ka_agree, try_sapling_compact_note_decryption,
try_sapling_note_decryption, try_sapling_output_recovery, Memo, SaplingNoteEncryption,
COMPACT_NOTE_SIZE, ENC_CIPHERTEXT_SIZE, OUT_CIPHERTEXT_SIZE,
};
use crate::{keys::OutgoingViewingKey, JUBJUB};
@ -594,6 +597,284 @@ mod tests {
assert_eq!(Memo::default().to_utf8(), None);
}
fn random_enc_ciphertext(
mut rng: &mut Rng,
) -> (
OutgoingViewingKey,
Fs,
edwards::Point<Bls12, Unknown>,
Fr,
edwards::Point<Bls12, PrimeOrder>,
[u8; ENC_CIPHERTEXT_SIZE],
[u8; OUT_CIPHERTEXT_SIZE],
) {
let diversifier = Diversifier([0; 11]);
let ivk = Fs::rand(&mut rng);
let pk_d = diversifier.g_d::<Bls12>(&JUBJUB).unwrap().mul(ivk, &JUBJUB);
let pa = PaymentAddress { diversifier, pk_d };
// Construct the value commitment for the proof instance
let value = 100;
let value_commitment = ValueCommitment::<Bls12> {
value,
randomness: Fs::rand(&mut rng),
};
let cv = value_commitment.cm(&JUBJUB).into();
let note = pa.create_note(value, Fs::rand(&mut rng), &JUBJUB).unwrap();
let cmu = note.cm(&JUBJUB);
let ovk = OutgoingViewingKey([0; 32]);
let ne = SaplingNoteEncryption::new(ovk, note, pa, Memo([0; 512]));
let epk = ne.epk();
let enc_ciphertext = ne.encrypt_note_plaintext();
let out_ciphertext = ne.encrypt_outgoing_plaintext(&cv, &cmu);
assert!(try_sapling_note_decryption(&ivk, epk, &cmu, &enc_ciphertext).is_some());
assert!(try_sapling_output_recovery(
&ovk,
&cv,
&cmu,
&epk,
&enc_ciphertext,
&out_ciphertext
)
.is_some());
(
ovk,
ivk,
cv,
cmu,
epk.clone(),
enc_ciphertext,
out_ciphertext,
)
}
#[test]
fn decryption_with_invalid_ivk() {
let mut rng = thread_rng();
let (_, _, _, cmu, epk, enc_ciphertext, _) = random_enc_ciphertext(&mut rng);
assert_eq!(
try_sapling_note_decryption(&Fs::rand(&mut rng), &epk, &cmu, &enc_ciphertext),
None
);
}
#[test]
fn decryption_with_invalid_epk() {
let mut rng = thread_rng();
let (_, ivk, _, cmu, _, enc_ciphertext, _) = random_enc_ciphertext(&mut rng);
assert_eq!(
try_sapling_note_decryption(
&ivk,
&edwards::Point::<Bls12, _>::rand(&mut rng, &JUBJUB).mul_by_cofactor(&JUBJUB),
&cmu,
&enc_ciphertext
),
None
);
}
#[test]
fn decryption_with_invalid_cmu() {
let mut rng = thread_rng();
let (_, ivk, _, _, epk, enc_ciphertext, _) = random_enc_ciphertext(&mut rng);
assert_eq!(
try_sapling_note_decryption(&ivk, &epk, &Fr::rand(&mut rng), &enc_ciphertext),
None
);
}
#[test]
fn decryption_with_invalid_tag() {
let mut rng = thread_rng();
let (_, ivk, _, cmu, epk, mut enc_ciphertext, _) = random_enc_ciphertext(&mut rng);
enc_ciphertext[ENC_CIPHERTEXT_SIZE - 1] ^= 0xff;
assert_eq!(
try_sapling_note_decryption(&ivk, &epk, &cmu, &enc_ciphertext),
None
);
}
#[test]
fn compact_decryption_with_invalid_ivk() {
let mut rng = thread_rng();
let (_, _, _, cmu, epk, enc_ciphertext, _) = random_enc_ciphertext(&mut rng);
assert_eq!(
try_sapling_compact_note_decryption(
&Fs::rand(&mut rng),
&epk,
&cmu,
&enc_ciphertext[..COMPACT_NOTE_SIZE]
),
None
);
}
#[test]
fn compact_decryption_with_invalid_epk() {
let mut rng = thread_rng();
let (_, ivk, _, cmu, _, enc_ciphertext, _) = random_enc_ciphertext(&mut rng);
assert_eq!(
try_sapling_compact_note_decryption(
&ivk,
&edwards::Point::<Bls12, _>::rand(&mut rng, &JUBJUB).mul_by_cofactor(&JUBJUB),
&cmu,
&enc_ciphertext[..COMPACT_NOTE_SIZE]
),
None
);
}
#[test]
fn compact_decryption_with_invalid_cmu() {
let mut rng = thread_rng();
let (_, ivk, _, _, epk, enc_ciphertext, _) = random_enc_ciphertext(&mut rng);
assert_eq!(
try_sapling_compact_note_decryption(
&ivk,
&epk,
&Fr::rand(&mut rng),
&enc_ciphertext[..COMPACT_NOTE_SIZE]
),
None
);
}
#[test]
fn compact_decryption_with_invalid_diversifier() {
let mut rng = thread_rng();
let (_, ivk, _, cmu, epk, mut enc_ciphertext, _) = random_enc_ciphertext(&mut rng);
// In compact decryption, this will result in an altered diversifier
enc_ciphertext[1] ^= 0xff;
assert_eq!(
try_sapling_compact_note_decryption(
&ivk,
&epk,
&cmu,
&enc_ciphertext[..COMPACT_NOTE_SIZE]
),
None
);
}
#[test]
fn recovery_with_invalid_ovk() {
let mut rng = thread_rng();
let (mut ovk, _, cv, cmu, epk, enc_ciphertext, out_ciphertext) =
random_enc_ciphertext(&mut rng);
ovk.0[0] ^= 0xff;
assert_eq!(
try_sapling_output_recovery(&ovk, &cv, &cmu, &epk, &enc_ciphertext, &out_ciphertext),
None
);
}
#[test]
fn recovery_with_invalid_cv() {
let mut rng = thread_rng();
let (ovk, _, _, cmu, epk, enc_ciphertext, out_ciphertext) = random_enc_ciphertext(&mut rng);
assert_eq!(
try_sapling_output_recovery(
&ovk,
&edwards::Point::<Bls12, _>::rand(&mut rng, &JUBJUB),
&cmu,
&epk,
&enc_ciphertext,
&out_ciphertext
),
None
);
}
#[test]
fn recovery_with_invalid_cmu() {
let mut rng = thread_rng();
let (ovk, _, cv, _, epk, enc_ciphertext, out_ciphertext) = random_enc_ciphertext(&mut rng);
assert_eq!(
try_sapling_output_recovery(
&ovk,
&cv,
&Fr::rand(&mut rng),
&epk,
&enc_ciphertext,
&out_ciphertext
),
None
);
}
#[test]
fn recovery_with_invalid_epk() {
let mut rng = thread_rng();
let (ovk, _, cv, cmu, _, enc_ciphertext, out_ciphertext) = random_enc_ciphertext(&mut rng);
assert_eq!(
try_sapling_output_recovery(
&ovk,
&cv,
&cmu,
&edwards::Point::<Bls12, _>::rand(&mut rng, &JUBJUB).mul_by_cofactor(&JUBJUB),
&enc_ciphertext,
&out_ciphertext
),
None
);
}
#[test]
fn recovery_with_invalid_enc_tag() {
let mut rng = thread_rng();
let (ovk, _, cv, cmu, epk, mut enc_ciphertext, out_ciphertext) =
random_enc_ciphertext(&mut rng);
enc_ciphertext[ENC_CIPHERTEXT_SIZE - 1] ^= 0xff;
assert_eq!(
try_sapling_output_recovery(&ovk, &cv, &cmu, &epk, &enc_ciphertext, &out_ciphertext),
None
);
}
#[test]
fn recovery_with_invalid_out_tag() {
let mut rng = thread_rng();
let (ovk, _, cv, cmu, epk, enc_ciphertext, mut out_ciphertext) =
random_enc_ciphertext(&mut rng);
out_ciphertext[OUT_CIPHERTEXT_SIZE - 1] ^= 0xff;
assert_eq!(
try_sapling_output_recovery(&ovk, &cv, &cmu, &epk, &enc_ciphertext, &out_ciphertext),
None
);
}
#[test]
fn test_vectors() {
let test_vectors = crate::test_vectors::note_encryption::make_test_vectors();