2021-03-12 16:04:13 -08:00
|
|
|
use group::GroupEncoding;
|
|
|
|
use pasta_curves::pallas;
|
|
|
|
|
|
|
|
use crate::{
|
|
|
|
keys::FullViewingKey,
|
|
|
|
spec::{prf_expand, to_base, to_scalar},
|
|
|
|
value::NoteValue,
|
|
|
|
Address,
|
|
|
|
};
|
|
|
|
|
|
|
|
mod commitment;
|
|
|
|
pub use self::commitment::NoteCommitment;
|
2021-01-20 12:09:09 -08:00
|
|
|
|
2021-03-15 18:27:08 -07:00
|
|
|
mod nullifier;
|
|
|
|
pub use self::nullifier::Nullifier;
|
|
|
|
|
2021-02-08 07:21:04 -08:00
|
|
|
/// The ZIP 212 seed randomness for a note.
|
|
|
|
#[derive(Debug)]
|
|
|
|
struct RandomSeed([u8; 32]);
|
|
|
|
|
|
|
|
impl RandomSeed {
|
2021-03-12 16:04:13 -08:00
|
|
|
/// Defined in [Zcash Protocol Spec § 4.7.3: Sending Notes (Orchard)][orchardsend].
|
|
|
|
///
|
|
|
|
/// [orchardsend]: https://zips.z.cash/protocol/nu5.pdf#orchardsend
|
|
|
|
fn psi(&self) -> pallas::Base {
|
|
|
|
to_base(prf_expand(&self.0, &[0x09]))
|
2021-02-08 07:21:04 -08:00
|
|
|
}
|
|
|
|
|
2021-03-12 16:04:13 -08:00
|
|
|
/// Defined in [Zcash Protocol Spec § 4.7.3: Sending Notes (Orchard)][orchardsend].
|
|
|
|
///
|
|
|
|
/// [orchardsend]: https://zips.z.cash/protocol/nu5.pdf#orchardsend
|
|
|
|
fn esk(&self) -> pallas::Scalar {
|
|
|
|
to_scalar(prf_expand(&self.0, &[0x04]))
|
2021-02-08 07:21:04 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-20 12:09:09 -08:00
|
|
|
/// A discrete amount of funds received by an address.
|
|
|
|
#[derive(Debug)]
|
2021-01-21 04:16:50 -08:00
|
|
|
pub struct Note {
|
2021-01-20 12:09:09 -08:00
|
|
|
/// The recipient of the funds.
|
2021-01-21 04:16:50 -08:00
|
|
|
recipient: Address,
|
2021-01-20 12:09:09 -08:00
|
|
|
/// The value of this note.
|
2021-01-21 04:16:50 -08:00
|
|
|
value: NoteValue,
|
2021-02-08 07:21:04 -08:00
|
|
|
/// A unique creation ID for this note.
|
|
|
|
///
|
|
|
|
/// This is set to the nullifier of the note that was spent in the [`Action`] that
|
|
|
|
/// created this note.
|
|
|
|
///
|
|
|
|
/// [`Action`]: crate::bundle::Action
|
|
|
|
rho: Nullifier,
|
|
|
|
/// The seed randomness for various note components.
|
|
|
|
rseed: RandomSeed,
|
2021-01-20 12:09:09 -08:00
|
|
|
}
|
|
|
|
|
2021-01-21 04:16:50 -08:00
|
|
|
impl Note {
|
2021-01-20 12:09:09 -08:00
|
|
|
/// Derives the commitment to this note.
|
2021-03-12 16:04:13 -08:00
|
|
|
///
|
|
|
|
/// Defined in [Zcash Protocol Spec § 3.2: Notes][notes].
|
|
|
|
///
|
|
|
|
/// [notes]: https://zips.z.cash/protocol/nu5.pdf#notes
|
2021-01-20 12:09:09 -08:00
|
|
|
pub fn commitment(&self) -> NoteCommitment {
|
2021-03-12 16:04:13 -08:00
|
|
|
let g_d = self.recipient.g_d();
|
|
|
|
|
2021-04-19 15:05:56 -07:00
|
|
|
// `Note` will always have a note commitment by construction.
|
2021-03-12 16:04:13 -08:00
|
|
|
NoteCommitment::derive(
|
|
|
|
g_d.to_bytes(),
|
|
|
|
self.recipient.pk_d().to_bytes(),
|
|
|
|
self.value,
|
|
|
|
self.rho.0,
|
|
|
|
self.rseed.psi(),
|
|
|
|
(&self.rseed).into(),
|
|
|
|
)
|
2021-04-19 15:05:56 -07:00
|
|
|
.unwrap()
|
2021-01-20 12:09:09 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Derives the nullifier for this note.
|
2021-03-15 18:27:08 -07:00
|
|
|
pub fn nullifier(&self, fvk: &FullViewingKey) -> Nullifier {
|
2021-03-29 17:52:20 -07:00
|
|
|
Nullifier::derive(fvk.nk(), self.rho.0, self.rseed.psi(), self.commitment())
|
2021-01-20 12:09:09 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// An encrypted note.
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct EncryptedNote;
|