Zebra/zebra-chain/src/sapling/spend.rs

59 lines
2.1 KiB
Rust

use std::io;
use crate::{
primitives::{
redjubjub::{self, SpendAuth},
Groth16Proof,
},
serialization::{
ReadZcashExt, SerializationError, WriteZcashExt, ZcashDeserialize, ZcashSerialize,
},
};
use super::{commitment, note, tree};
/// A _Spend Description_, as described in [protocol specification §7.3][ps].
///
/// [ps]: https://zips.z.cash/protocol/protocol.pdf#spendencoding
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct Spend {
/// A value commitment to the value of the input note.
pub cv: commitment::ValueCommitment,
/// A root of the Sapling note commitment tree at some block height in the past.
pub anchor: tree::Root,
/// The nullifier of the input note.
pub nullifier: note::Nullifier,
/// The randomized public key for `spend_auth_sig`.
pub rk: redjubjub::VerificationKeyBytes<SpendAuth>,
/// The ZK spend proof.
pub zkproof: Groth16Proof,
/// A signature authorizing this spend.
pub spend_auth_sig: redjubjub::Signature<SpendAuth>,
}
impl ZcashSerialize for Spend {
fn zcash_serialize<W: io::Write>(&self, mut writer: W) -> Result<(), io::Error> {
self.cv.zcash_serialize(&mut writer)?;
writer.write_all(&self.anchor.0[..])?;
writer.write_32_bytes(&self.nullifier.into())?;
writer.write_all(&<[u8; 32]>::from(self.rk)[..])?;
self.zkproof.zcash_serialize(&mut writer)?;
writer.write_all(&<[u8; 64]>::from(self.spend_auth_sig)[..])?;
Ok(())
}
}
impl ZcashDeserialize for Spend {
fn zcash_deserialize<R: io::Read>(mut reader: R) -> Result<Self, SerializationError> {
use crate::sapling::{commitment::ValueCommitment, note::Nullifier};
Ok(Spend {
cv: ValueCommitment::zcash_deserialize(&mut reader)?,
anchor: tree::Root(reader.read_32_bytes()?),
nullifier: Nullifier::from(reader.read_32_bytes()?),
rk: reader.read_32_bytes()?.into(),
zkproof: Groth16Proof::zcash_deserialize(&mut reader)?,
spend_auth_sig: reader.read_64_bytes()?.into(),
})
}
}