mirror of
https://github.com/Qortal/pirate-librustzcash.git
synced 2025-01-30 23:42:13 +00:00
Check note plaintext version byte when decrypting
This commit is contained in:
parent
060977fe54
commit
fdb6e208db
@ -351,6 +351,12 @@ fn parse_note_plaintext_without_memo(
|
||||
cmu: &Fr,
|
||||
plaintext: &[u8],
|
||||
) -> Option<(Note<Bls12>, PaymentAddress<Bls12>)> {
|
||||
// Check note plaintext version
|
||||
match plaintext[0] {
|
||||
0x01 => (),
|
||||
_ => return None,
|
||||
}
|
||||
|
||||
let mut d = [0u8; 11];
|
||||
d.copy_from_slice(&plaintext[1..12]);
|
||||
|
||||
@ -508,6 +514,12 @@ pub fn try_sapling_output_recovery(
|
||||
NOTE_PLAINTEXT_SIZE
|
||||
);
|
||||
|
||||
// Check note plaintext version
|
||||
match plaintext[0] {
|
||||
0x01 => (),
|
||||
_ => return None,
|
||||
}
|
||||
|
||||
let mut d = [0u8; 11];
|
||||
d.copy_from_slice(&plaintext[1..12]);
|
||||
|
||||
@ -543,6 +555,7 @@ pub fn try_sapling_output_recovery(
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crypto_api_chachapoly::ChachaPolyIetf;
|
||||
use ff::{PrimeField, PrimeFieldRepr};
|
||||
use pairing::bls12_381::{Bls12, Fr, FrRepr};
|
||||
use rand::{thread_rng, Rand, Rng};
|
||||
@ -558,7 +571,8 @@ mod tests {
|
||||
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,
|
||||
COMPACT_NOTE_SIZE, ENC_CIPHERTEXT_SIZE, NOTE_PLAINTEXT_SIZE, OUT_CIPHERTEXT_SIZE,
|
||||
OUT_PLAINTEXT_SIZE,
|
||||
};
|
||||
use crate::{keys::OutgoingViewingKey, JUBJUB};
|
||||
|
||||
@ -738,6 +752,60 @@ mod tests {
|
||||
)
|
||||
}
|
||||
|
||||
fn reencrypt_enc_ciphertext(
|
||||
ovk: &OutgoingViewingKey,
|
||||
cv: &edwards::Point<Bls12, Unknown>,
|
||||
cmu: &Fr,
|
||||
epk: &edwards::Point<Bls12, PrimeOrder>,
|
||||
enc_ciphertext: &mut [u8; ENC_CIPHERTEXT_SIZE],
|
||||
out_ciphertext: &[u8; OUT_CIPHERTEXT_SIZE],
|
||||
modify_plaintext: impl Fn(&mut [u8; NOTE_PLAINTEXT_SIZE]),
|
||||
) {
|
||||
let ock = prf_ock(&ovk, &cv, &cmu, &epk);
|
||||
|
||||
let mut op = [0; OUT_CIPHERTEXT_SIZE];
|
||||
assert_eq!(
|
||||
ChachaPolyIetf::aead_cipher()
|
||||
.open_to(&mut op, out_ciphertext, &[], ock.as_bytes(), &[0u8; 12])
|
||||
.unwrap(),
|
||||
OUT_PLAINTEXT_SIZE
|
||||
);
|
||||
|
||||
let pk_d = edwards::Point::<Bls12, _>::read(&op[0..32], &JUBJUB)
|
||||
.unwrap()
|
||||
.as_prime_order(&JUBJUB)
|
||||
.unwrap();
|
||||
|
||||
let mut esk = FsRepr::default();
|
||||
esk.read_le(&op[32..OUT_PLAINTEXT_SIZE]).unwrap();
|
||||
let esk = Fs::from_repr(esk).unwrap();
|
||||
|
||||
let shared_secret = sapling_ka_agree(&esk, &pk_d);
|
||||
let key = kdf_sapling(shared_secret, &epk);
|
||||
|
||||
let mut plaintext = {
|
||||
let mut buf = [0; ENC_CIPHERTEXT_SIZE];
|
||||
assert_eq!(
|
||||
ChachaPolyIetf::aead_cipher()
|
||||
.open_to(&mut buf, enc_ciphertext, &[], key.as_bytes(), &[0u8; 12])
|
||||
.unwrap(),
|
||||
NOTE_PLAINTEXT_SIZE
|
||||
);
|
||||
let mut pt = [0; NOTE_PLAINTEXT_SIZE];
|
||||
pt.copy_from_slice(&buf[..NOTE_PLAINTEXT_SIZE]);
|
||||
pt
|
||||
};
|
||||
|
||||
modify_plaintext(&mut plaintext);
|
||||
|
||||
assert_eq!(
|
||||
ChachaPolyIetf::aead_cipher()
|
||||
.seal_to(enc_ciphertext, &plaintext, &[], &key.as_bytes(), &[0u8; 12])
|
||||
.unwrap(),
|
||||
ENC_CIPHERTEXT_SIZE
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decryption_with_invalid_ivk() {
|
||||
let mut rng = thread_rng();
|
||||
@ -792,6 +860,28 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decryption_with_invalid_version_byte() {
|
||||
let mut rng = thread_rng();
|
||||
|
||||
let (ovk, ivk, cv, cmu, epk, mut enc_ciphertext, out_ciphertext) =
|
||||
random_enc_ciphertext(&mut rng);
|
||||
|
||||
reencrypt_enc_ciphertext(
|
||||
&ovk,
|
||||
&cv,
|
||||
&cmu,
|
||||
&epk,
|
||||
&mut enc_ciphertext,
|
||||
&out_ciphertext,
|
||||
|pt| pt[0] = 0x02,
|
||||
);
|
||||
assert_eq!(
|
||||
try_sapling_note_decryption(&ivk, &epk, &cmu, &enc_ciphertext),
|
||||
None
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn compact_decryption_with_invalid_ivk() {
|
||||
let mut rng = thread_rng();
|
||||
@ -843,6 +933,33 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn compact_decryption_with_invalid_version_byte() {
|
||||
let mut rng = thread_rng();
|
||||
|
||||
let (ovk, ivk, cv, cmu, epk, mut enc_ciphertext, out_ciphertext) =
|
||||
random_enc_ciphertext(&mut rng);
|
||||
|
||||
reencrypt_enc_ciphertext(
|
||||
&ovk,
|
||||
&cv,
|
||||
&cmu,
|
||||
&epk,
|
||||
&mut enc_ciphertext,
|
||||
&out_ciphertext,
|
||||
|pt| pt[0] = 0x02,
|
||||
);
|
||||
assert_eq!(
|
||||
try_sapling_compact_note_decryption(
|
||||
&ivk,
|
||||
&epk,
|
||||
&cmu,
|
||||
&enc_ciphertext[..COMPACT_NOTE_SIZE]
|
||||
),
|
||||
None
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn compact_decryption_with_invalid_diversifier() {
|
||||
let mut rng = thread_rng();
|
||||
@ -961,6 +1078,28 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn recovery_with_invalid_version_byte() {
|
||||
let mut rng = thread_rng();
|
||||
|
||||
let (ovk, _, cv, cmu, epk, mut enc_ciphertext, out_ciphertext) =
|
||||
random_enc_ciphertext(&mut rng);
|
||||
|
||||
reencrypt_enc_ciphertext(
|
||||
&ovk,
|
||||
&cv,
|
||||
&cmu,
|
||||
&epk,
|
||||
&mut enc_ciphertext,
|
||||
&out_ciphertext,
|
||||
|pt| pt[0] = 0x02,
|
||||
);
|
||||
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();
|
||||
|
Loading…
Reference in New Issue
Block a user