zcash_note_encryption: Constrain `ShieldedOutput` ciphertext size
Previously we were returning the ciphertext as a slice, and then
asserting its length within the APIs the caller passed it into. Now
instead we require the caller to define whether or not the output is
compact, to make the API more predictable.
This doesn't place any additional constraints on users of this trait,
because the assertions already prevented a full output from being passed
to a compact trial decryption API.
Extracted from: 4fcd83d74e
This commit is contained in:
parent
7ab76d8574
commit
1ac6d5b8fe
|
@ -5,14 +5,14 @@ use core::iter;
|
|||
|
||||
use crate::{
|
||||
try_compact_note_decryption_inner, try_note_decryption_inner, BatchDomain, EphemeralKeyBytes,
|
||||
ShieldedOutput,
|
||||
ShieldedOutput, COMPACT_NOTE_SIZE, ENC_CIPHERTEXT_SIZE,
|
||||
};
|
||||
|
||||
/// Trial decryption of a batch of notes with a set of recipients.
|
||||
///
|
||||
/// This is the batched version of [`crate::try_note_decryption`].
|
||||
#[allow(clippy::type_complexity)]
|
||||
pub fn try_note_decryption<D: BatchDomain, Output: ShieldedOutput<D>>(
|
||||
pub fn try_note_decryption<D: BatchDomain, Output: ShieldedOutput<D, ENC_CIPHERTEXT_SIZE>>(
|
||||
ivks: &[D::IncomingViewingKey],
|
||||
outputs: &[(D, Output)],
|
||||
) -> Vec<Option<(D::Note, D::Recipient, D::Memo)>> {
|
||||
|
@ -22,14 +22,14 @@ pub fn try_note_decryption<D: BatchDomain, Output: ShieldedOutput<D>>(
|
|||
/// Trial decryption of a batch of notes for light clients with a set of recipients.
|
||||
///
|
||||
/// This is the batched version of [`crate::try_compact_note_decryption`].
|
||||
pub fn try_compact_note_decryption<D: BatchDomain, Output: ShieldedOutput<D>>(
|
||||
pub fn try_compact_note_decryption<D: BatchDomain, Output: ShieldedOutput<D, COMPACT_NOTE_SIZE>>(
|
||||
ivks: &[D::IncomingViewingKey],
|
||||
outputs: &[(D, Output)],
|
||||
) -> Vec<Option<(D::Note, D::Recipient)>> {
|
||||
batch_note_decryption(ivks, outputs, try_compact_note_decryption_inner)
|
||||
}
|
||||
|
||||
fn batch_note_decryption<D: BatchDomain, Output: ShieldedOutput<D>, F, FR>(
|
||||
fn batch_note_decryption<D: BatchDomain, Output: ShieldedOutput<D, CS>, F, FR, const CS: usize>(
|
||||
ivks: &[D::IncomingViewingKey],
|
||||
outputs: &[(D, Output)],
|
||||
decrypt_inner: F,
|
||||
|
|
20
src/lib.rs
20
src/lib.rs
|
@ -206,10 +206,10 @@ pub trait BatchDomain: Domain {
|
|||
}
|
||||
}
|
||||
|
||||
pub trait ShieldedOutput<D: Domain> {
|
||||
pub trait ShieldedOutput<D: Domain, const CIPHERTEXT_SIZE: usize> {
|
||||
fn ephemeral_key(&self) -> EphemeralKeyBytes;
|
||||
fn cmstar_bytes(&self) -> D::ExtractedCommitmentBytes;
|
||||
fn enc_ciphertext(&self) -> &[u8];
|
||||
fn enc_ciphertext(&self) -> &[u8; CIPHERTEXT_SIZE];
|
||||
}
|
||||
|
||||
/// A struct containing context required for encrypting Sapling and Orchard notes.
|
||||
|
@ -389,7 +389,7 @@ impl<D: Domain> NoteEncryption<D> {
|
|||
///
|
||||
/// Implements section 4.19.2 of the
|
||||
/// [Zcash Protocol Specification](https://zips.z.cash/protocol/nu5.pdf#decryptivk).
|
||||
pub fn try_note_decryption<D: Domain, Output: ShieldedOutput<D>>(
|
||||
pub fn try_note_decryption<D: Domain, Output: ShieldedOutput<D, ENC_CIPHERTEXT_SIZE>>(
|
||||
domain: &D,
|
||||
ivk: &D::IncomingViewingKey,
|
||||
output: &Output,
|
||||
|
@ -403,7 +403,7 @@ pub fn try_note_decryption<D: Domain, Output: ShieldedOutput<D>>(
|
|||
try_note_decryption_inner(domain, ivk, &ephemeral_key, output, key)
|
||||
}
|
||||
|
||||
fn try_note_decryption_inner<D: Domain, Output: ShieldedOutput<D>>(
|
||||
fn try_note_decryption_inner<D: Domain, Output: ShieldedOutput<D, ENC_CIPHERTEXT_SIZE>>(
|
||||
domain: &D,
|
||||
ivk: &D::IncomingViewingKey,
|
||||
ephemeral_key: &EphemeralKeyBytes,
|
||||
|
@ -411,7 +411,6 @@ fn try_note_decryption_inner<D: Domain, Output: ShieldedOutput<D>>(
|
|||
key: D::SymmetricKey,
|
||||
) -> Option<(D::Note, D::Recipient, D::Memo)> {
|
||||
let enc_ciphertext = output.enc_ciphertext();
|
||||
assert_eq!(enc_ciphertext.len(), ENC_CIPHERTEXT_SIZE);
|
||||
|
||||
let mut plaintext =
|
||||
NotePlaintextBytes(enc_ciphertext[..NOTE_PLAINTEXT_SIZE].try_into().unwrap());
|
||||
|
@ -487,7 +486,7 @@ fn check_note_validity<D: Domain>(
|
|||
/// Implements the procedure specified in [`ZIP 307`].
|
||||
///
|
||||
/// [`ZIP 307`]: https://zips.z.cash/zip-0307
|
||||
pub fn try_compact_note_decryption<D: Domain, Output: ShieldedOutput<D>>(
|
||||
pub fn try_compact_note_decryption<D: Domain, Output: ShieldedOutput<D, COMPACT_NOTE_SIZE>>(
|
||||
domain: &D,
|
||||
ivk: &D::IncomingViewingKey,
|
||||
output: &Output,
|
||||
|
@ -501,15 +500,13 @@ pub fn try_compact_note_decryption<D: Domain, Output: ShieldedOutput<D>>(
|
|||
try_compact_note_decryption_inner(domain, ivk, &ephemeral_key, output, key)
|
||||
}
|
||||
|
||||
fn try_compact_note_decryption_inner<D: Domain, Output: ShieldedOutput<D>>(
|
||||
fn try_compact_note_decryption_inner<D: Domain, Output: ShieldedOutput<D, COMPACT_NOTE_SIZE>>(
|
||||
domain: &D,
|
||||
ivk: &D::IncomingViewingKey,
|
||||
ephemeral_key: &EphemeralKeyBytes,
|
||||
output: &Output,
|
||||
key: D::SymmetricKey,
|
||||
) -> Option<(D::Note, D::Recipient)> {
|
||||
assert_eq!(output.enc_ciphertext().len(), COMPACT_NOTE_SIZE);
|
||||
|
||||
// Start from block 1 to skip over Poly1305 keying output
|
||||
let mut plaintext = [0; COMPACT_NOTE_SIZE];
|
||||
plaintext.copy_from_slice(output.enc_ciphertext());
|
||||
|
@ -535,7 +532,7 @@ fn try_compact_note_decryption_inner<D: Domain, Output: ShieldedOutput<D>>(
|
|||
/// Implements [Zcash Protocol Specification section 4.19.3][decryptovk].
|
||||
///
|
||||
/// [decryptovk]: https://zips.z.cash/protocol/nu5.pdf#decryptovk
|
||||
pub fn try_output_recovery_with_ovk<D: Domain, Output: ShieldedOutput<D>>(
|
||||
pub fn try_output_recovery_with_ovk<D: Domain, Output: ShieldedOutput<D, ENC_CIPHERTEXT_SIZE>>(
|
||||
domain: &D,
|
||||
ovk: &D::OutgoingViewingKey,
|
||||
output: &Output,
|
||||
|
@ -555,14 +552,13 @@ pub fn try_output_recovery_with_ovk<D: Domain, Output: ShieldedOutput<D>>(
|
|||
/// Implements part of section 4.19.3 of the
|
||||
/// [Zcash Protocol Specification](https://zips.z.cash/protocol/nu5.pdf#decryptovk).
|
||||
/// For decryption using a Full Viewing Key see [`try_output_recovery_with_ovk`].
|
||||
pub fn try_output_recovery_with_ock<D: Domain, Output: ShieldedOutput<D>>(
|
||||
pub fn try_output_recovery_with_ock<D: Domain, Output: ShieldedOutput<D, ENC_CIPHERTEXT_SIZE>>(
|
||||
domain: &D,
|
||||
ock: &OutgoingCipherKey,
|
||||
output: &Output,
|
||||
out_ciphertext: &[u8],
|
||||
) -> Option<(D::Note, D::Recipient, D::Memo)> {
|
||||
let enc_ciphertext = output.enc_ciphertext();
|
||||
assert_eq!(enc_ciphertext.len(), ENC_CIPHERTEXT_SIZE);
|
||||
assert_eq!(out_ciphertext.len(), OUT_CIPHERTEXT_SIZE);
|
||||
|
||||
let mut op = OutPlaintextBytes([0; OUT_PLAINTEXT_SIZE]);
|
||||
|
|
Loading…
Reference in New Issue