mirror of https://github.com/zcash/halo2.git
commit
0ccb0101df
18
src/keys.rs
18
src/keys.rs
|
@ -8,6 +8,7 @@ use fpe::ff1::{BinaryNumeralString, FF1};
|
|||
use group::GroupEncoding;
|
||||
use halo2::arithmetic::FieldExt;
|
||||
use pasta_curves::pallas;
|
||||
use rand::RngCore;
|
||||
use subtle::CtOption;
|
||||
|
||||
use crate::{
|
||||
|
@ -28,6 +29,23 @@ use crate::{
|
|||
pub struct SpendingKey([u8; 32]);
|
||||
|
||||
impl SpendingKey {
|
||||
/// Generates a random spending key.
|
||||
///
|
||||
/// This is only used when generating dummy notes. Real spending keys should be
|
||||
/// derived according to [ZIP 32].
|
||||
///
|
||||
/// [ZIP 32]: https://zips.z.cash/zip-0032
|
||||
pub(crate) fn random(rng: &mut impl RngCore) -> Self {
|
||||
loop {
|
||||
let mut bytes = [0; 32];
|
||||
rng.fill_bytes(&mut bytes);
|
||||
let sk = SpendingKey::from_bytes(bytes);
|
||||
if sk.is_some().into() {
|
||||
break sk.unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Constructs an Orchard spending key from uniformly-random bytes.
|
||||
///
|
||||
/// Returns `None` if the bytes do not correspond to a valid Orchard spending key.
|
||||
|
|
28
src/note.rs
28
src/note.rs
|
@ -1,8 +1,9 @@
|
|||
use group::GroupEncoding;
|
||||
use pasta_curves::pallas;
|
||||
use rand::RngCore;
|
||||
|
||||
use crate::{
|
||||
keys::FullViewingKey,
|
||||
keys::{FullViewingKey, SpendingKey},
|
||||
spec::{prf_expand, to_base, to_scalar},
|
||||
value::NoteValue,
|
||||
Address,
|
||||
|
@ -19,6 +20,12 @@ pub use self::nullifier::Nullifier;
|
|||
struct RandomSeed([u8; 32]);
|
||||
|
||||
impl RandomSeed {
|
||||
pub(crate) fn random(rng: &mut impl RngCore) -> Self {
|
||||
let mut bytes = [0; 32];
|
||||
rng.fill_bytes(&mut bytes);
|
||||
RandomSeed(bytes)
|
||||
}
|
||||
|
||||
/// Defined in [Zcash Protocol Spec § 4.7.3: Sending Notes (Orchard)][orchardsend].
|
||||
///
|
||||
/// [orchardsend]: https://zips.z.cash/protocol/nu5.pdf#orchardsend
|
||||
|
@ -53,6 +60,25 @@ pub struct Note {
|
|||
}
|
||||
|
||||
impl Note {
|
||||
/// Generates a dummy spent note.
|
||||
///
|
||||
/// Defined in [Zcash Protocol Spec § 4.8.3: Dummy Notes (Orchard)][orcharddummynotes].
|
||||
///
|
||||
/// [orcharddummynotes]: https://zips.z.cash/protocol/nu5.pdf#orcharddummynotes
|
||||
pub(crate) fn dummy(rng: &mut impl RngCore, rho: Option<Nullifier>) -> (FullViewingKey, Self) {
|
||||
let fvk: FullViewingKey = (&SpendingKey::random(rng)).into();
|
||||
let recipient = fvk.default_address();
|
||||
|
||||
let note = Note {
|
||||
recipient,
|
||||
value: NoteValue::zero(),
|
||||
rho: rho.unwrap_or_else(|| Nullifier::dummy(rng)),
|
||||
rseed: RandomSeed::random(rng),
|
||||
};
|
||||
|
||||
(fvk, note)
|
||||
}
|
||||
|
||||
/// Derives the commitment to this note.
|
||||
///
|
||||
/// Defined in [Zcash Protocol Spec § 3.2: Notes][notes].
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
use group::Group;
|
||||
use halo2::arithmetic::CurveExt;
|
||||
use pasta_curves::pallas;
|
||||
use rand::RngCore;
|
||||
|
||||
use super::NoteCommitment;
|
||||
use crate::{
|
||||
|
@ -12,6 +14,22 @@ use crate::{
|
|||
pub struct Nullifier(pub(super) pallas::Base);
|
||||
|
||||
impl Nullifier {
|
||||
/// Generates a dummy nullifier for use as $\rho$ in dummy spent notes.
|
||||
///
|
||||
/// Nullifiers are required by consensus to be unique. For dummy output notes, we get
|
||||
/// this restriction as intended: the note's $\rho$ value is set to the nullifier of
|
||||
/// the accompanying spent note within the action, which is constrained by consensus
|
||||
/// to be unique. In the case of dummy spent notes, we get this restriction by
|
||||
/// following the chain backwards: the nullifier of the dummy spent note will be
|
||||
/// constrained by consensus to be unique, and the nullifier's uniqueness is derived
|
||||
/// from the uniqueness of $\rho$.
|
||||
///
|
||||
/// Instead of explicitly sampling for a unique nullifier, we rely here on the size of
|
||||
/// the base field to make the chance of sapling a colliding nullifier negligible.
|
||||
pub(crate) fn dummy(rng: &mut impl RngCore) -> Self {
|
||||
Nullifier(extract_p(&pallas::Point::random(rng)))
|
||||
}
|
||||
|
||||
/// $DeriveNullifier$.
|
||||
///
|
||||
/// Defined in [Zcash Protocol Spec § 4.16: Note Commitments and Nullifiers][commitmentsandnullifiers].
|
||||
|
|
|
@ -47,6 +47,11 @@ impl std::error::Error for OverflowError {}
|
|||
pub struct NoteValue(u64);
|
||||
|
||||
impl NoteValue {
|
||||
pub(crate) fn zero() -> Self {
|
||||
// Default for u64 is zero.
|
||||
Default::default()
|
||||
}
|
||||
|
||||
pub(crate) fn to_le_bits(self) -> BitArray<Lsb0, [u8; 8]> {
|
||||
BitArray::<Lsb0, _>::new(self.0.to_le_bytes())
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue