zcash_note_encryption: Move domain batch APIs into a BatchDomain trait

These are the only allocating APIs; this change makes it possible to
make the crate no-std compatible.


Extracted from: 35e7542065
This commit is contained in:
Jack Grigg 2021-11-17 12:14:26 +00:00
parent 709c25bcdf
commit df51fbc543
2 changed files with 35 additions and 33 deletions

View File

@ -3,7 +3,7 @@
use std::iter;
use crate::{
try_compact_note_decryption_inner, try_note_decryption_inner, Domain, EphemeralKeyBytes,
try_compact_note_decryption_inner, try_note_decryption_inner, BatchDomain, EphemeralKeyBytes,
ShieldedOutput,
};
@ -11,7 +11,7 @@ use crate::{
///
/// This is the batched version of [`crate::try_note_decryption`].
#[allow(clippy::type_complexity)]
pub fn try_note_decryption<D: Domain, Output: ShieldedOutput<D>>(
pub fn try_note_decryption<D: BatchDomain, Output: ShieldedOutput<D>>(
ivks: &[D::IncomingViewingKey],
outputs: &[(D, Output)],
) -> Vec<Option<(D::Note, D::Recipient, D::Memo)>> {
@ -21,14 +21,14 @@ pub fn try_note_decryption<D: Domain, 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: Domain, Output: ShieldedOutput<D>>(
pub fn try_compact_note_decryption<D: BatchDomain, Output: ShieldedOutput<D>>(
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: Domain, Output: ShieldedOutput<D>, F, FR>(
fn batch_note_decryption<D: BatchDomain, Output: ShieldedOutput<D>, F, FR>(
ivks: &[D::IncomingViewingKey],
outputs: &[(D, Output)],
decrypt_inner: F,

View File

@ -116,19 +116,6 @@ pub trait Domain {
fn kdf(secret: Self::SharedSecret, ephemeral_key: &EphemeralKeyBytes) -> Self::SymmetricKey;
/// Computes `Self::kdf` on a batch of items.
///
/// For each item in the batch, if the shared secret is `None`, this returns `None` at
/// that position.
fn batch_kdf<'a>(
items: impl Iterator<Item = (Option<Self::SharedSecret>, &'a EphemeralKeyBytes)>,
) -> Vec<Option<Self::SymmetricKey>> {
// Default implementation: do the non-batched thing.
items
.map(|(secret, ephemeral_key)| secret.map(|secret| Self::kdf(secret, ephemeral_key)))
.collect()
}
// for right now, we just need `recipient` to get `d`; in the future when we
// can get that from a Sapling note, the recipient parameter will be able
// to be removed.
@ -154,22 +141,6 @@ pub trait Domain {
fn epk(ephemeral_key: &EphemeralKeyBytes) -> Option<Self::EphemeralPublicKey>;
/// Computes `Self::epk` on a batch of ephemeral keys.
///
/// This is useful for protocols where the underlying curve requires an inversion to
/// parse an encoded point.
///
/// For usability, this returns tuples of the ephemeral keys and the result of parsing
/// them.
fn batch_epk(
ephemeral_keys: impl Iterator<Item = EphemeralKeyBytes>,
) -> Vec<(Option<Self::EphemeralPublicKey>, EphemeralKeyBytes)> {
// Default implementation: do the non-batched thing.
ephemeral_keys
.map(|ephemeral_key| (Self::epk(&ephemeral_key), ephemeral_key))
.collect()
}
fn check_epk_bytes<F: Fn(&Self::EphemeralSecretKey) -> NoteValidity>(
note: &Self::Note,
check: F,
@ -203,6 +174,37 @@ pub trait Domain {
fn extract_esk(out_plaintext: &[u8; OUT_PLAINTEXT_SIZE]) -> Option<Self::EphemeralSecretKey>;
}
pub trait BatchDomain: Domain {
/// Computes `Self::kdf` on a batch of items.
///
/// For each item in the batch, if the shared secret is `None`, this returns `None` at
/// that position.
fn batch_kdf<'a>(
items: impl Iterator<Item = (Option<Self::SharedSecret>, &'a EphemeralKeyBytes)>,
) -> Vec<Option<Self::SymmetricKey>> {
// Default implementation: do the non-batched thing.
items
.map(|(secret, ephemeral_key)| secret.map(|secret| Self::kdf(secret, ephemeral_key)))
.collect()
}
/// Computes `Self::epk` on a batch of ephemeral keys.
///
/// This is useful for protocols where the underlying curve requires an inversion to
/// parse an encoded point.
///
/// For usability, this returns tuples of the ephemeral keys and the result of parsing
/// them.
fn batch_epk(
ephemeral_keys: impl Iterator<Item = EphemeralKeyBytes>,
) -> Vec<(Option<Self::EphemeralPublicKey>, EphemeralKeyBytes)> {
// Default implementation: do the non-batched thing.
ephemeral_keys
.map(|ephemeral_key| (Self::epk(&ephemeral_key), ephemeral_key))
.collect()
}
}
pub trait ShieldedOutput<D: Domain> {
fn ephemeral_key(&self) -> EphemeralKeyBytes;
fn cmstar_bytes(&self) -> D::ExtractedCommitmentBytes;