parent
4ccec84768
commit
b6385ca36f
|
@ -0,0 +1,4 @@
|
||||||
|
//! Note and value commitments and associated types.
|
||||||
|
|
||||||
|
pub mod sapling;
|
||||||
|
pub mod sprout;
|
|
@ -1,4 +1,9 @@
|
||||||
//! Sapling note and value commitments
|
//! Sapling note and value commitments and types.
|
||||||
|
|
||||||
|
#![allow(clippy::unit_arg)]
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod arbitrary;
|
||||||
|
|
||||||
use std::{fmt, io};
|
use std::{fmt, io};
|
||||||
|
|
||||||
|
@ -7,6 +12,7 @@ use rand_core::{CryptoRng, RngCore};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
keys::sapling::{find_group_hash, Diversifier, TransmissionKey},
|
keys::sapling::{find_group_hash, Diversifier, TransmissionKey},
|
||||||
|
notes::sapling::Note,
|
||||||
serde_helpers,
|
serde_helpers,
|
||||||
serialization::{ReadZcashExt, SerializationError, ZcashDeserialize, ZcashSerialize},
|
serialization::{ReadZcashExt, SerializationError, ZcashDeserialize, ZcashSerialize},
|
||||||
types::amount::{Amount, NonNegative},
|
types::amount::{Amount, NonNegative},
|
||||||
|
@ -125,14 +131,38 @@ impl From<jubjub::ExtendedPoint> for NoteCommitment {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Eq for NoteCommitment {}
|
|
||||||
|
|
||||||
impl From<NoteCommitment> for [u8; 32] {
|
impl From<NoteCommitment> for [u8; 32] {
|
||||||
fn from(cm: NoteCommitment) -> [u8; 32] {
|
fn from(cm: NoteCommitment) -> [u8; 32] {
|
||||||
cm.0.to_bytes()
|
cm.0.to_bytes()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<Note> for NoteCommitment {
|
||||||
|
/// Construct a “windowed” Pedersen commitment by reusing a
|
||||||
|
/// Perderson hash constructon, and adding a randomized point on
|
||||||
|
/// the Jubjub curve.
|
||||||
|
///
|
||||||
|
/// WindowedPedersenCommit_r (s) := \
|
||||||
|
/// PedersenHashToPoint(“Zcash_PH”, s) + [r]FindGroupHash^J^(r)∗(“Zcash_PH”, “r”)
|
||||||
|
///
|
||||||
|
/// NoteCommit^Sapling_rcm (g*_d , pk*_d , v) := \
|
||||||
|
/// WindowedPedersenCommit_rcm([1; 6] || I2LEBSP_64(v) || g*_d || pk*_d)
|
||||||
|
///
|
||||||
|
/// https://zips.z.cash/protocol/protocol.pdf#concretewindowedcommit
|
||||||
|
fn from(note: Note) -> NoteCommitment {
|
||||||
|
use rand_core::OsRng;
|
||||||
|
|
||||||
|
NoteCommitment::new(
|
||||||
|
&mut OsRng,
|
||||||
|
note.diversifier,
|
||||||
|
note.transmission_key,
|
||||||
|
note.value,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Eq for NoteCommitment {}
|
||||||
|
|
||||||
impl ZcashSerialize for NoteCommitment {
|
impl ZcashSerialize for NoteCommitment {
|
||||||
fn zcash_serialize<W: io::Write>(&self, mut writer: W) -> Result<(), io::Error> {
|
fn zcash_serialize<W: io::Write>(&self, mut writer: W) -> Result<(), io::Error> {
|
||||||
writer.write_all(&self.0.to_bytes())?;
|
writer.write_all(&self.0.to_bytes())?;
|
|
@ -0,0 +1,33 @@
|
||||||
|
use proptest::{arbitrary::any, array, prelude::*};
|
||||||
|
|
||||||
|
use crate::commitments::sapling;
|
||||||
|
|
||||||
|
impl Arbitrary for sapling::NoteCommitment {
|
||||||
|
type Parameters = ();
|
||||||
|
|
||||||
|
fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
|
||||||
|
array::uniform32(any::<u8>())
|
||||||
|
.prop_filter("Valid jubjub::AffinePoint", |b| {
|
||||||
|
jubjub::AffinePoint::from_bytes(*b).is_some().unwrap_u8() == 1
|
||||||
|
})
|
||||||
|
.prop_map(Self::from)
|
||||||
|
.boxed()
|
||||||
|
}
|
||||||
|
|
||||||
|
type Strategy = BoxedStrategy<Self>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Arbitrary for sapling::ValueCommitment {
|
||||||
|
type Parameters = ();
|
||||||
|
|
||||||
|
fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
|
||||||
|
array::uniform32(any::<u8>())
|
||||||
|
.prop_filter("Valid jubjub::AffinePoint", |b| {
|
||||||
|
jubjub::AffinePoint::from_bytes(*b).is_some().unwrap_u8() == 1
|
||||||
|
})
|
||||||
|
.prop_map(Self::from)
|
||||||
|
.boxed()
|
||||||
|
}
|
||||||
|
|
||||||
|
type Strategy = BoxedStrategy<Self>;
|
||||||
|
}
|
|
@ -1,6 +1,15 @@
|
||||||
|
//! Sprout commitment types.
|
||||||
|
|
||||||
|
#![allow(clippy::unit_arg)]
|
||||||
|
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
use crate::serialization::{ReadZcashExt, SerializationError, ZcashDeserialize, ZcashSerialize};
|
use sha2::{Digest, Sha256};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
notes::sprout::Note,
|
||||||
|
serialization::{ReadZcashExt, SerializationError, ZcashDeserialize, ZcashSerialize},
|
||||||
|
};
|
||||||
|
|
||||||
/// The randomness used in the Pedersen Hash for note commitment.
|
/// The randomness used in the Pedersen Hash for note commitment.
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||||
|
@ -18,6 +27,22 @@ impl AsRef<[u8]> for CommitmentRandomness {
|
||||||
#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
|
#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
|
||||||
pub struct NoteCommitment(pub(crate) [u8; 32]);
|
pub struct NoteCommitment(pub(crate) [u8; 32]);
|
||||||
|
|
||||||
|
impl From<Note> for NoteCommitment {
|
||||||
|
/// NoteCommit_rcm^Sprout(a_pk, v, rho)
|
||||||
|
///
|
||||||
|
/// https://zips.z.cash/protocol/protocol.pdf#concretesproutnotecommit
|
||||||
|
fn from(note: Note) -> NoteCommitment {
|
||||||
|
let leading_byte: u8 = 0xB0;
|
||||||
|
let mut hasher = Sha256::default();
|
||||||
|
hasher.input([leading_byte]);
|
||||||
|
hasher.input(note.paying_key);
|
||||||
|
hasher.input(note.value.to_bytes());
|
||||||
|
hasher.input(note.rho);
|
||||||
|
hasher.input(note.rcm);
|
||||||
|
NoteCommitment(hasher.result().into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ZcashSerialize for NoteCommitment {
|
impl ZcashSerialize for NoteCommitment {
|
||||||
fn zcash_serialize<W: io::Write>(&self, mut writer: W) -> Result<(), io::Error> {
|
fn zcash_serialize<W: io::Write>(&self, mut writer: W) -> Result<(), io::Error> {
|
||||||
writer.write_all(&self.0[..])?;
|
writer.write_all(&self.0[..])?;
|
|
@ -17,6 +17,7 @@ mod sha256d_writer;
|
||||||
|
|
||||||
pub mod addresses;
|
pub mod addresses;
|
||||||
pub mod block;
|
pub mod block;
|
||||||
|
pub mod commitments;
|
||||||
pub mod equihash_solution;
|
pub mod equihash_solution;
|
||||||
pub mod keys;
|
pub mod keys;
|
||||||
pub mod notes;
|
pub mod notes;
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
//! Notes, note and value commitments, note encryption, and nullifier types.
|
//! Notes, note encryption, and nullifier types.
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod arbitrary;
|
||||||
mod memo;
|
mod memo;
|
||||||
|
|
||||||
pub mod sapling;
|
pub mod sapling;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::notes::memo::Memo;
|
use crate::notes::memo::Memo;
|
||||||
|
|
||||||
use proptest::{arbitrary::any, array, collection::vec, prelude::*};
|
use proptest::{arbitrary::any, collection::vec, prelude::*};
|
||||||
|
|
||||||
impl Arbitrary for Memo {
|
impl Arbitrary for Memo {
|
||||||
type Parameters = ();
|
type Parameters = ();
|
||||||
|
|
|
@ -6,51 +6,33 @@
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod arbitrary;
|
mod arbitrary;
|
||||||
mod ciphertexts;
|
mod ciphertexts;
|
||||||
mod commitments;
|
|
||||||
mod nullifiers;
|
mod nullifiers;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
commitments::sapling::CommitmentRandomness,
|
||||||
keys::sapling::{Diversifier, TransmissionKey},
|
keys::sapling::{Diversifier, TransmissionKey},
|
||||||
notes::memo::Memo,
|
notes::memo::Memo,
|
||||||
types::amount::{Amount, NonNegative},
|
types::amount::{Amount, NonNegative},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use ciphertexts::{EncryptedCiphertext, OutCiphertext};
|
pub use ciphertexts::{EncryptedCiphertext, OutCiphertext};
|
||||||
pub use commitments::{CommitmentRandomness, NoteCommitment, ValueCommitment};
|
|
||||||
pub use nullifiers::Nullifier;
|
pub use nullifiers::Nullifier;
|
||||||
|
|
||||||
/// A Note represents that a value is spendable by the recipient who
|
/// A Note represents that a value is spendable by the recipient who
|
||||||
/// holds the spending key corresponding to a given shielded payment
|
/// holds the spending key corresponding to a given shielded payment
|
||||||
/// address.
|
/// address.
|
||||||
pub struct Note {
|
pub struct Note {
|
||||||
diversifier: Diversifier,
|
/// The diversier of the recipient’s shielded payment address.
|
||||||
transmission_key: TransmissionKey,
|
pub diversifier: Diversifier,
|
||||||
value: Amount<NonNegative>,
|
/// The diversied transmission key of the recipient’s shielded
|
||||||
rcm: CommitmentRandomness,
|
/// payment address.
|
||||||
}
|
pub transmission_key: TransmissionKey,
|
||||||
|
/// An integer representing the value of the note in zatoshi.
|
||||||
impl Note {
|
pub value: Amount<NonNegative>,
|
||||||
/// Construct a “windowed” Pedersen commitment by reusing a
|
/// A random commitment trapdoor used to produce the associated
|
||||||
/// Perderson hash constructon, and adding a randomized point on
|
/// note commitment.
|
||||||
/// the Jubjub curve.
|
pub rcm: CommitmentRandomness,
|
||||||
///
|
|
||||||
/// WindowedPedersenCommit_r (s) := \
|
|
||||||
/// PedersenHashToPoint(“Zcash_PH”, s) + [r]FindGroupHash^J^(r)∗(“Zcash_PH”, “r”)
|
|
||||||
///
|
|
||||||
/// NoteCommit^Sapling_rcm (g*_d , pk*_d , v) := \
|
|
||||||
/// WindowedPedersenCommit_rcm([1; 6] || I2LEBSP_64(v) || g*_d || pk*_d)
|
|
||||||
///
|
|
||||||
/// https://zips.z.cash/protocol/protocol.pdf#concretewindowedcommit
|
|
||||||
pub fn commit(&self) -> NoteCommitment {
|
|
||||||
use rand_core::OsRng;
|
|
||||||
|
|
||||||
NoteCommitment::new(
|
|
||||||
&mut OsRng,
|
|
||||||
self.diversifier,
|
|
||||||
self.transmission_key,
|
|
||||||
self.value,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The decrypted form of encrypted Sapling notes on the blockchain.
|
/// The decrypted form of encrypted Sapling notes on the blockchain.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use proptest::{arbitrary::any, array, collection::vec, prelude::*};
|
use proptest::{arbitrary::any, collection::vec, prelude::*};
|
||||||
|
|
||||||
use crate::notes::sapling;
|
use crate::notes::sapling;
|
||||||
|
|
||||||
|
@ -33,33 +33,3 @@ impl Arbitrary for sapling::OutCiphertext {
|
||||||
|
|
||||||
type Strategy = BoxedStrategy<Self>;
|
type Strategy = BoxedStrategy<Self>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Arbitrary for sapling::NoteCommitment {
|
|
||||||
type Parameters = ();
|
|
||||||
|
|
||||||
fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
|
|
||||||
array::uniform32(any::<u8>())
|
|
||||||
.prop_filter("Valid jubjub::AffinePoint", |b| {
|
|
||||||
jubjub::AffinePoint::from_bytes(*b).is_some().unwrap_u8() == 1
|
|
||||||
})
|
|
||||||
.prop_map(Self::from)
|
|
||||||
.boxed()
|
|
||||||
}
|
|
||||||
|
|
||||||
type Strategy = BoxedStrategy<Self>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Arbitrary for sapling::ValueCommitment {
|
|
||||||
type Parameters = ();
|
|
||||||
|
|
||||||
fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
|
|
||||||
array::uniform32(any::<u8>())
|
|
||||||
.prop_filter("Valid jubjub::AffinePoint", |b| {
|
|
||||||
jubjub::AffinePoint::from_bytes(*b).is_some().unwrap_u8() == 1
|
|
||||||
})
|
|
||||||
.prop_map(Self::from)
|
|
||||||
.boxed()
|
|
||||||
}
|
|
||||||
|
|
||||||
type Strategy = BoxedStrategy<Self>;
|
|
||||||
}
|
|
||||||
|
|
|
@ -6,19 +6,17 @@
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod arbitrary;
|
mod arbitrary;
|
||||||
mod ciphertexts;
|
mod ciphertexts;
|
||||||
mod commitments;
|
|
||||||
mod nullifiers;
|
mod nullifiers;
|
||||||
|
|
||||||
use sha2::{Digest, Sha256};
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
commitments::sprout::CommitmentRandomness,
|
||||||
keys::sprout::PayingKey,
|
keys::sprout::PayingKey,
|
||||||
notes::memo::Memo,
|
notes::memo::Memo,
|
||||||
types::amount::{Amount, NonNegative},
|
types::amount::{Amount, NonNegative},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use ciphertexts::EncryptedCiphertext;
|
pub use ciphertexts::EncryptedCiphertext;
|
||||||
pub use commitments::{CommitmentRandomness, NoteCommitment};
|
|
||||||
pub use nullifiers::{Nullifier, NullifierSeed};
|
pub use nullifiers::{Nullifier, NullifierSeed};
|
||||||
|
|
||||||
/// A Note represents that a value is spendable by the recipient who
|
/// A Note represents that a value is spendable by the recipient who
|
||||||
|
@ -30,30 +28,14 @@ pub use nullifiers::{Nullifier, NullifierSeed};
|
||||||
#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
|
#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
|
||||||
pub struct Note {
|
pub struct Note {
|
||||||
/// The paying key of the recipient’s shielded payment address
|
/// The paying key of the recipient’s shielded payment address
|
||||||
paying_key: PayingKey,
|
pub paying_key: PayingKey,
|
||||||
/// An integer representing the value of the note in zatoshi (1 ZEC
|
/// An integer representing the value of the note in zatoshi (1 ZEC
|
||||||
/// = 10^8 zatoshi)
|
/// = 10^8 zatoshi)
|
||||||
value: Amount<NonNegative>,
|
pub value: Amount<NonNegative>,
|
||||||
/// Input to PRF^nf to derive the nullifier of the note
|
/// Input to PRF^nf to derive the nullifier of the note
|
||||||
rho: NullifierSeed,
|
pub rho: NullifierSeed,
|
||||||
/// A random commitment trapdoor
|
/// A random commitment trapdoor
|
||||||
rcm: CommitmentRandomness,
|
pub rcm: CommitmentRandomness,
|
||||||
}
|
|
||||||
|
|
||||||
impl Note {
|
|
||||||
/// NoteCommit_rcm^Sprout(a_pk, v, rho)
|
|
||||||
///
|
|
||||||
/// https://zips.z.cash/protocol/protocol.pdf#concretesproutnotecommit
|
|
||||||
pub fn commit(&self) -> NoteCommitment {
|
|
||||||
let leading_byte: u8 = 0xB0;
|
|
||||||
let mut hasher = Sha256::default();
|
|
||||||
hasher.input([leading_byte]);
|
|
||||||
hasher.input(self.paying_key);
|
|
||||||
hasher.input(self.value.to_bytes());
|
|
||||||
hasher.input(self.rho);
|
|
||||||
hasher.input(self.rcm);
|
|
||||||
NoteCommitment(hasher.result().into())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The decrypted form of encrypted Sprout notes on the blockchain.
|
/// The decrypted form of encrypted Sprout notes on the blockchain.
|
||||||
|
|
|
@ -1,22 +1,6 @@
|
||||||
use proptest::{arbitrary::any, collection::vec, prelude::*};
|
use proptest::{arbitrary::any, collection::vec, prelude::*};
|
||||||
|
|
||||||
use crate::notes::{memo::Memo, sprout};
|
use crate::notes::sprout;
|
||||||
|
|
||||||
impl Arbitrary for Memo {
|
|
||||||
type Parameters = ();
|
|
||||||
|
|
||||||
fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
|
|
||||||
(vec(any::<u8>(), 512))
|
|
||||||
.prop_map(|v| {
|
|
||||||
let mut bytes = [0; 512];
|
|
||||||
bytes.copy_from_slice(v.as_slice());
|
|
||||||
Memo(Box::new(bytes))
|
|
||||||
})
|
|
||||||
.boxed()
|
|
||||||
}
|
|
||||||
|
|
||||||
type Strategy = BoxedStrategy<Self>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Arbitrary for sprout::EncryptedCiphertext {
|
impl Arbitrary for sprout::EncryptedCiphertext {
|
||||||
type Parameters = ();
|
type Parameters = ();
|
||||||
|
|
|
@ -9,7 +9,7 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
notes,
|
commitments, notes,
|
||||||
proofs::ZkSnarkProof,
|
proofs::ZkSnarkProof,
|
||||||
serialization::{
|
serialization::{
|
||||||
ReadZcashExt, SerializationError, WriteZcashExt, ZcashDeserialize, ZcashSerialize,
|
ReadZcashExt, SerializationError, WriteZcashExt, ZcashDeserialize, ZcashSerialize,
|
||||||
|
@ -335,7 +335,7 @@ impl ZcashDeserialize for Spend {
|
||||||
fn zcash_deserialize<R: io::Read>(mut reader: R) -> Result<Self, SerializationError> {
|
fn zcash_deserialize<R: io::Read>(mut reader: R) -> Result<Self, SerializationError> {
|
||||||
use crate::treestate::note_commitment_tree::SaplingNoteTreeRootHash;
|
use crate::treestate::note_commitment_tree::SaplingNoteTreeRootHash;
|
||||||
Ok(Spend {
|
Ok(Spend {
|
||||||
cv: notes::sapling::ValueCommitment::zcash_deserialize(&mut reader)?,
|
cv: commitments::sapling::ValueCommitment::zcash_deserialize(&mut reader)?,
|
||||||
anchor: SaplingNoteTreeRootHash(reader.read_32_bytes()?),
|
anchor: SaplingNoteTreeRootHash(reader.read_32_bytes()?),
|
||||||
nullifier: notes::sapling::Nullifier::zcash_deserialize(&mut reader)?,
|
nullifier: notes::sapling::Nullifier::zcash_deserialize(&mut reader)?,
|
||||||
rk: reader.read_32_bytes()?.into(),
|
rk: reader.read_32_bytes()?.into(),
|
||||||
|
@ -360,7 +360,7 @@ impl ZcashSerialize for Output {
|
||||||
impl ZcashDeserialize for Output {
|
impl ZcashDeserialize for Output {
|
||||||
fn zcash_deserialize<R: io::Read>(mut reader: R) -> Result<Self, SerializationError> {
|
fn zcash_deserialize<R: io::Read>(mut reader: R) -> Result<Self, SerializationError> {
|
||||||
Ok(Output {
|
Ok(Output {
|
||||||
cv: notes::sapling::ValueCommitment::zcash_deserialize(&mut reader)?,
|
cv: commitments::sapling::ValueCommitment::zcash_deserialize(&mut reader)?,
|
||||||
cm_u: jubjub::Fq::from_bytes(&reader.read_32_bytes()?).unwrap(),
|
cm_u: jubjub::Fq::from_bytes(&reader.read_32_bytes()?).unwrap(),
|
||||||
ephemeral_key: jubjub::AffinePoint::from_bytes(reader.read_32_bytes()?).unwrap(),
|
ephemeral_key: jubjub::AffinePoint::from_bytes(reader.read_32_bytes()?).unwrap(),
|
||||||
enc_ciphertext: notes::sapling::EncryptedCiphertext::zcash_deserialize(&mut reader)?,
|
enc_ciphertext: notes::sapling::EncryptedCiphertext::zcash_deserialize(&mut reader)?,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
notes,
|
commitments, notes,
|
||||||
proofs::Groth16Proof,
|
proofs::Groth16Proof,
|
||||||
redjubjub::{self, Binding, SpendAuth},
|
redjubjub::{self, Binding, SpendAuth},
|
||||||
serde_helpers,
|
serde_helpers,
|
||||||
|
@ -13,7 +13,7 @@ use futures::future::Either;
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
pub struct Spend {
|
pub struct Spend {
|
||||||
/// A value commitment to the value of the input note.
|
/// A value commitment to the value of the input note.
|
||||||
pub cv: notes::sapling::ValueCommitment,
|
pub cv: commitments::sapling::ValueCommitment,
|
||||||
/// A root of the Sapling note commitment tree at some block height in the past.
|
/// A root of the Sapling note commitment tree at some block height in the past.
|
||||||
pub anchor: SaplingNoteTreeRootHash,
|
pub anchor: SaplingNoteTreeRootHash,
|
||||||
/// The nullifier of the input note.
|
/// The nullifier of the input note.
|
||||||
|
@ -32,7 +32,7 @@ pub struct Spend {
|
||||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||||
pub struct Output {
|
pub struct Output {
|
||||||
/// A value commitment to the value of the input note.
|
/// A value commitment to the value of the input note.
|
||||||
pub cv: notes::sapling::ValueCommitment,
|
pub cv: commitments::sapling::ValueCommitment,
|
||||||
/// The u-coordinate of the note commitment for the output note.
|
/// The u-coordinate of the note commitment for the output note.
|
||||||
#[serde(with = "serde_helpers::Fq")]
|
#[serde(with = "serde_helpers::Fq")]
|
||||||
pub cm_u: jubjub::Fq,
|
pub cm_u: jubjub::Fq,
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
|
commitments,
|
||||||
notes::{sapling, sprout},
|
notes::{sapling, sprout},
|
||||||
proofs::{Groth16Proof, ZkSnarkProof},
|
proofs::{Groth16Proof, ZkSnarkProof},
|
||||||
transaction::{
|
transaction::{
|
||||||
|
@ -94,8 +95,8 @@ impl Arbitrary for Output {
|
||||||
|
|
||||||
fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
|
fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
|
||||||
(
|
(
|
||||||
any::<sapling::ValueCommitment>(),
|
any::<commitments::sapling::ValueCommitment>(),
|
||||||
any::<sapling::NoteCommitment>(),
|
any::<commitments::sapling::NoteCommitment>(),
|
||||||
array::uniform32(any::<u8>()).prop_filter("Valid jubjub::AffinePoint", |b| {
|
array::uniform32(any::<u8>()).prop_filter("Valid jubjub::AffinePoint", |b| {
|
||||||
jubjub::AffinePoint::from_bytes(*b).is_some().unwrap_u8() == 1
|
jubjub::AffinePoint::from_bytes(*b).is_some().unwrap_u8() == 1
|
||||||
}),
|
}),
|
||||||
|
@ -154,7 +155,7 @@ impl Arbitrary for Spend {
|
||||||
fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
|
fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
|
||||||
(
|
(
|
||||||
any::<SaplingNoteTreeRootHash>(),
|
any::<SaplingNoteTreeRootHash>(),
|
||||||
any::<sapling::ValueCommitment>(),
|
any::<commitments::sapling::ValueCommitment>(),
|
||||||
any::<sapling::Nullifier>(),
|
any::<sapling::Nullifier>(),
|
||||||
array::uniform32(any::<u8>()),
|
array::uniform32(any::<u8>()),
|
||||||
any::<Groth16Proof>(),
|
any::<Groth16Proof>(),
|
||||||
|
|
Loading…
Reference in New Issue