Move nullifiers to respective note modules, pull in existing types from keys
This commit is contained in:
parent
8b78a55c71
commit
2c285985c8
|
@ -169,6 +169,12 @@ impl From<SpendingKey> for ReceivingKey {
|
||||||
#[derive(Copy, Clone, Eq, PartialEq)]
|
#[derive(Copy, Clone, Eq, PartialEq)]
|
||||||
pub struct PayingKey(pub [u8; 32]);
|
pub struct PayingKey(pub [u8; 32]);
|
||||||
|
|
||||||
|
impl AsRef<[u8]> for PayingKey {
|
||||||
|
fn as_ref(&self) -> &[u8] {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl fmt::Debug for PayingKey {
|
impl fmt::Debug for PayingKey {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
f.debug_tuple("PayingKey")
|
f.debug_tuple("PayingKey")
|
||||||
|
|
|
@ -21,7 +21,6 @@ pub mod equihash_solution;
|
||||||
pub mod keys;
|
pub mod keys;
|
||||||
pub mod note_commitment_tree;
|
pub mod note_commitment_tree;
|
||||||
pub mod notes;
|
pub mod notes;
|
||||||
pub mod nullifier;
|
|
||||||
pub mod parameters;
|
pub mod parameters;
|
||||||
pub mod proofs;
|
pub mod proofs;
|
||||||
pub mod serialization;
|
pub mod serialization;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
//!
|
//!
|
||||||
|
#![allow(clippy::unit_arg)]
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
use std::{fmt, io};
|
use std::{fmt, io};
|
||||||
|
@ -6,27 +7,46 @@ use std::{fmt, io};
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
use proptest::{arbitrary::Arbitrary, collection::vec, prelude::*};
|
use proptest::{arbitrary::Arbitrary, collection::vec, prelude::*};
|
||||||
|
|
||||||
use crate::serde_helpers;
|
|
||||||
use crate::serialization::{SerializationError, ZcashDeserialize, ZcashSerialize};
|
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use crate::{
|
||||||
|
keys::sapling::{Diversifier, TransmissionKey},
|
||||||
|
serde_helpers,
|
||||||
|
serialization::{ReadZcashExt, SerializationError, ZcashDeserialize, ZcashSerialize},
|
||||||
|
types::amount::{Amount, NonNegative},
|
||||||
|
};
|
||||||
|
|
||||||
/// A _Diversifier_, an 11 byte value used to randomize the
|
/// A Nullifier for Sapling transactions
|
||||||
/// recipient's final public shielded payment address to create a
|
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
/// _diversified payment address_.
|
#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
|
||||||
///
|
pub struct Nullifier([u8; 32]);
|
||||||
/// When used, this value is mapped to an affine JubJub group element.
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
pub struct Diversifier(pub [u8; 11]);
|
|
||||||
|
|
||||||
///
|
impl From<[u8; 32]> for Nullifier {
|
||||||
|
fn from(buf: [u8; 32]) -> Self {
|
||||||
|
Self(buf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ZcashDeserialize for Nullifier {
|
||||||
|
fn zcash_deserialize<R: io::Read>(mut reader: R) -> Result<Self, SerializationError> {
|
||||||
|
let bytes = reader.read_32_bytes()?;
|
||||||
|
|
||||||
|
Ok(Self(bytes))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ZcashSerialize for Nullifier {
|
||||||
|
fn zcash_serialize<W: io::Write>(&self, mut writer: W) -> Result<(), io::Error> {
|
||||||
|
writer.write_all(&self.0[..])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A Note represents that a value is spendable by the recipient who
|
||||||
|
/// holds the spending key corresponding to a given shielded payment
|
||||||
|
/// address.
|
||||||
pub struct Note {
|
pub struct Note {
|
||||||
diversifier: Diversifier,
|
diversifier: Diversifier,
|
||||||
// TODO: refine as a type, derived from a scalar mult of the
|
transmission_key: TransmissionKey,
|
||||||
// diversifier as a jubjub group element and the incoming view key
|
value: Amount<NonNegative>,
|
||||||
// scalar.
|
|
||||||
transmission_key: [u8; 32],
|
|
||||||
value: u64,
|
|
||||||
note_commitment_randomness: NoteCommitmentRandomness,
|
note_commitment_randomness: NoteCommitmentRandomness,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,29 +1,70 @@
|
||||||
//!
|
//!
|
||||||
|
#![allow(clippy::unit_arg)]
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
use super::{memo::Memo, *};
|
use std::{fmt, io};
|
||||||
use crate::serde_helpers;
|
|
||||||
use crate::serialization::{SerializationError, ZcashDeserialize, ZcashSerialize};
|
|
||||||
use crate::types::amount::{Amount, NonNegative};
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use sha2::{Digest, Sha256};
|
use sha2::{Digest, Sha256};
|
||||||
use std::{
|
|
||||||
fmt,
|
use crate::{
|
||||||
io::{self},
|
keys::sprout::PayingKey,
|
||||||
|
serde_helpers,
|
||||||
|
serialization::{ReadZcashExt, SerializationError, ZcashDeserialize, ZcashSerialize},
|
||||||
|
types::amount::{Amount, NonNegative},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use super::{memo::Memo, *};
|
||||||
|
|
||||||
|
/// Nullifier seed, named rho in the [spec][ps].
|
||||||
///
|
///
|
||||||
|
/// [ps]: https://zips.z.cash/protocol/protocol.pdf#sproutkeycomponents
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
struct NullifierSeed([u8; 32]);
|
||||||
|
|
||||||
|
impl AsRef<[u8]> for NullifierSeed {
|
||||||
|
fn as_ref(&self) -> &[u8] {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A Nullifier Set for Sprout transactions
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
|
||||||
|
pub struct Nullifier([u8; 32]);
|
||||||
|
|
||||||
|
impl From<[u8; 32]> for Nullifier {
|
||||||
|
fn from(buf: [u8; 32]) -> Self {
|
||||||
|
Self(buf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ZcashDeserialize for Nullifier {
|
||||||
|
fn zcash_deserialize<R: io::Read>(mut reader: R) -> Result<Self, SerializationError> {
|
||||||
|
let bytes = reader.read_32_bytes()?;
|
||||||
|
|
||||||
|
Ok(Self(bytes))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ZcashSerialize for Nullifier {
|
||||||
|
fn zcash_serialize<W: io::Write>(&self, mut writer: W) -> Result<(), io::Error> {
|
||||||
|
writer.write_all(&self.0[..])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A Note represents that a value is spendable by the recipient who
|
||||||
|
/// holds the spending key corresponding to a given shielded payment
|
||||||
|
/// address.
|
||||||
pub struct Note {
|
pub struct Note {
|
||||||
// TODO: refine type as a SHA-256d output derived from a spending key.
|
paying_key: PayingKey,
|
||||||
paying_key: [u8; 32],
|
|
||||||
value: Amount<NonNegative>,
|
value: Amount<NonNegative>,
|
||||||
// TODO: refine type as the input to the PRF that results in a nullifier.
|
nullifier_seed: NullifierSeed,
|
||||||
nullifier_seed: [u8; 32],
|
|
||||||
note_commitment_randomness: NoteCommitmentRandomness,
|
note_commitment_randomness: NoteCommitmentRandomness,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Note {
|
impl Note {
|
||||||
pub fn note_commitment(&self) -> NoteCommitment {
|
pub fn commitment(&self) -> NoteCommitment {
|
||||||
let leading_byte: u8 = 0xB0;
|
let leading_byte: u8 = 0xB0;
|
||||||
let mut hasher = Sha256::default();
|
let mut hasher = Sha256::default();
|
||||||
hasher.input([leading_byte]);
|
hasher.input([leading_byte]);
|
||||||
|
@ -31,14 +72,13 @@ impl Note {
|
||||||
hasher.input(self.value.to_bytes());
|
hasher.input(self.value.to_bytes());
|
||||||
hasher.input(self.nullifier_seed);
|
hasher.input(self.nullifier_seed);
|
||||||
hasher.input(self.note_commitment_randomness);
|
hasher.input(self.note_commitment_randomness);
|
||||||
let hash = hasher.result().into();
|
|
||||||
NoteCommitment { hash }
|
NoteCommitment(hasher.result().into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct NoteCommitment {
|
///
|
||||||
hash: [u8; 32],
|
pub struct NoteCommitment([u8; 32]);
|
||||||
}
|
|
||||||
|
|
||||||
/// The decrypted form of encrypted Sprout notes on the blockchain.
|
/// The decrypted form of encrypted Sprout notes on the blockchain.
|
||||||
pub struct NotePlaintext {
|
pub struct NotePlaintext {
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
//! Nullifier set types for sprout and sapling
|
|
||||||
|
|
||||||
pub mod sapling;
|
|
||||||
pub mod sprout;
|
|
|
@ -1,30 +0,0 @@
|
||||||
//! Sapling Nullifier Set types and impls
|
|
||||||
#![allow(clippy::unit_arg)]
|
|
||||||
use crate::serialization::{ReadZcashExt, SerializationError, ZcashDeserialize, ZcashSerialize};
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use std::io;
|
|
||||||
|
|
||||||
/// A Nullifier Set for Sapling transactions
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
|
||||||
#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
|
|
||||||
pub struct Nullifier([u8; 32]);
|
|
||||||
|
|
||||||
impl From<[u8; 32]> for Nullifier {
|
|
||||||
fn from(buf: [u8; 32]) -> Self {
|
|
||||||
Self(buf)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ZcashDeserialize for Nullifier {
|
|
||||||
fn zcash_deserialize<R: io::Read>(mut reader: R) -> Result<Self, SerializationError> {
|
|
||||||
let bytes = reader.read_32_bytes()?;
|
|
||||||
|
|
||||||
Ok(Self(bytes))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ZcashSerialize for Nullifier {
|
|
||||||
fn zcash_serialize<W: io::Write>(&self, mut writer: W) -> Result<(), io::Error> {
|
|
||||||
writer.write_all(&self.0[..])
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,30 +0,0 @@
|
||||||
//! Sprout Nullifier Set types and impls
|
|
||||||
#![allow(clippy::unit_arg)]
|
|
||||||
use crate::serialization::{ReadZcashExt, SerializationError, ZcashDeserialize, ZcashSerialize};
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use std::io;
|
|
||||||
|
|
||||||
/// A Nullifier Set for Sprout transactions
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
|
||||||
#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
|
|
||||||
pub struct Nullifier([u8; 32]);
|
|
||||||
|
|
||||||
impl From<[u8; 32]> for Nullifier {
|
|
||||||
fn from(buf: [u8; 32]) -> Self {
|
|
||||||
Self(buf)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ZcashDeserialize for Nullifier {
|
|
||||||
fn zcash_deserialize<R: io::Read>(mut reader: R) -> Result<Self, SerializationError> {
|
|
||||||
let bytes = reader.read_32_bytes()?;
|
|
||||||
|
|
||||||
Ok(Self(bytes))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ZcashSerialize for Nullifier {
|
|
||||||
fn zcash_serialize<W: io::Write>(&self, mut writer: W) -> Result<(), io::Error> {
|
|
||||||
writer.write_all(&self.0[..])
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -23,7 +23,7 @@ pub struct JoinSplit<P: ZkSnarkProof> {
|
||||||
/// A nullifier for the input notes.
|
/// A nullifier for the input notes.
|
||||||
///
|
///
|
||||||
/// XXX refine type to [T; 2] -- there are two nullifiers
|
/// XXX refine type to [T; 2] -- there are two nullifiers
|
||||||
pub nullifiers: [crate::nullifier::sprout::Nullifier; 2],
|
pub nullifiers: [crate::notes::sprout::Nullifier; 2],
|
||||||
/// A note commitment for this output note.
|
/// A note commitment for this output note.
|
||||||
///
|
///
|
||||||
/// XXX refine type to [T; 2] -- there are two commitments
|
/// XXX refine type to [T; 2] -- there are two commitments
|
||||||
|
|
|
@ -262,8 +262,8 @@ impl<P: ZkSnarkProof> ZcashDeserialize for JoinSplit<P> {
|
||||||
vpub_new: reader.read_u64::<LittleEndian>()?.try_into()?,
|
vpub_new: reader.read_u64::<LittleEndian>()?.try_into()?,
|
||||||
anchor: reader.read_32_bytes()?,
|
anchor: reader.read_32_bytes()?,
|
||||||
nullifiers: [
|
nullifiers: [
|
||||||
crate::nullifier::sprout::Nullifier::zcash_deserialize(&mut reader)?,
|
crate::notes::sprout::Nullifier::zcash_deserialize(&mut reader)?,
|
||||||
crate::nullifier::sprout::Nullifier::zcash_deserialize(&mut reader)?,
|
crate::notes::sprout::Nullifier::zcash_deserialize(&mut reader)?,
|
||||||
],
|
],
|
||||||
commitments: [reader.read_32_bytes()?, reader.read_32_bytes()?],
|
commitments: [reader.read_32_bytes()?, reader.read_32_bytes()?],
|
||||||
ephemeral_key: x25519_dalek::PublicKey::from(reader.read_32_bytes()?),
|
ephemeral_key: x25519_dalek::PublicKey::from(reader.read_32_bytes()?),
|
||||||
|
@ -335,7 +335,7 @@ impl ZcashDeserialize for Spend {
|
||||||
Ok(Spend {
|
Ok(Spend {
|
||||||
cv: reader.read_32_bytes()?,
|
cv: reader.read_32_bytes()?,
|
||||||
anchor: SaplingNoteTreeRootHash(reader.read_32_bytes()?),
|
anchor: SaplingNoteTreeRootHash(reader.read_32_bytes()?),
|
||||||
nullifier: crate::nullifier::sapling::Nullifier::zcash_deserialize(&mut reader)?,
|
nullifier: crate::notes::sapling::Nullifier::zcash_deserialize(&mut reader)?,
|
||||||
rk: reader.read_32_bytes()?.into(),
|
rk: reader.read_32_bytes()?.into(),
|
||||||
zkproof: Groth16Proof::zcash_deserialize(&mut reader)?,
|
zkproof: Groth16Proof::zcash_deserialize(&mut reader)?,
|
||||||
spend_auth_sig: reader.read_64_bytes()?.into(),
|
spend_auth_sig: reader.read_64_bytes()?.into(),
|
||||||
|
|
|
@ -18,7 +18,7 @@ pub struct Spend {
|
||||||
/// 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.
|
||||||
pub nullifier: crate::nullifier::sapling::Nullifier,
|
pub nullifier: crate::notes::sapling::Nullifier,
|
||||||
/// The randomized public key for `spend_auth_sig`.
|
/// The randomized public key for `spend_auth_sig`.
|
||||||
pub rk: redjubjub::VerificationKeyBytes<SpendAuth>,
|
pub rk: redjubjub::VerificationKeyBytes<SpendAuth>,
|
||||||
/// The ZK spend proof.
|
/// The ZK spend proof.
|
||||||
|
|
|
@ -22,7 +22,7 @@ impl<P: ZkSnarkProof + Arbitrary + 'static> Arbitrary for JoinSplit<P> {
|
||||||
any::<Amount<NonNegative>>(),
|
any::<Amount<NonNegative>>(),
|
||||||
any::<Amount<NonNegative>>(),
|
any::<Amount<NonNegative>>(),
|
||||||
array::uniform32(any::<u8>()),
|
array::uniform32(any::<u8>()),
|
||||||
array::uniform2(any::<crate::nullifier::sprout::Nullifier>()),
|
array::uniform2(any::<crate::notes::sprout::Nullifier>()),
|
||||||
array::uniform2(array::uniform32(any::<u8>())),
|
array::uniform2(array::uniform32(any::<u8>())),
|
||||||
array::uniform32(any::<u8>()),
|
array::uniform32(any::<u8>()),
|
||||||
array::uniform32(any::<u8>()),
|
array::uniform32(any::<u8>()),
|
||||||
|
@ -155,7 +155,7 @@ impl Arbitrary for Spend {
|
||||||
(
|
(
|
||||||
array::uniform32(any::<u8>()),
|
array::uniform32(any::<u8>()),
|
||||||
any::<SaplingNoteTreeRootHash>(),
|
any::<SaplingNoteTreeRootHash>(),
|
||||||
any::<crate::nullifier::sapling::Nullifier>(),
|
any::<crate::notes::sapling::Nullifier>(),
|
||||||
array::uniform32(any::<u8>()),
|
array::uniform32(any::<u8>()),
|
||||||
any::<Groth16Proof>(),
|
any::<Groth16Proof>(),
|
||||||
vec(any::<u8>(), 64),
|
vec(any::<u8>(), 64),
|
||||||
|
|
Loading…
Reference in New Issue