Refactor Sapling nullifier derivation
This commit is contained in:
parent
f1d3e03a9b
commit
65271b49e5
|
@ -8,6 +8,7 @@ pub mod note_encryption;
|
|||
pub mod pedersen_hash;
|
||||
pub mod prover;
|
||||
pub mod redjubjub;
|
||||
mod spec;
|
||||
mod tree;
|
||||
pub mod util;
|
||||
pub mod value;
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use blake2s_simd::Params as Blake2sParams;
|
||||
use byteorder::{LittleEndian, WriteBytesExt};
|
||||
use group::{
|
||||
ff::{Field, PrimeField},
|
||||
|
@ -84,22 +83,7 @@ impl Note {
|
|||
/// Computes the nullifier given the nullifier deriving key and
|
||||
/// note position
|
||||
pub fn nf(&self, nk: &NullifierDerivingKey, position: u64) -> Nullifier {
|
||||
// Compute rho = cm + position.G
|
||||
let rho = self.cm_full_point()
|
||||
+ (constants::NULLIFIER_POSITION_GENERATOR * jubjub::Fr::from(position));
|
||||
|
||||
// Compute nf = BLAKE2s(nk | rho)
|
||||
Nullifier::from_slice(
|
||||
Blake2sParams::new()
|
||||
.hash_length(32)
|
||||
.personal(constants::PRF_NF_PERSONALIZATION)
|
||||
.to_state()
|
||||
.update(&nk.0.to_bytes())
|
||||
.update(&rho.to_bytes())
|
||||
.finalize()
|
||||
.as_bytes(),
|
||||
)
|
||||
.unwrap()
|
||||
Nullifier::derive(nk, self.cm_full_point(), position)
|
||||
}
|
||||
|
||||
/// Computes the note commitment
|
||||
|
|
|
@ -2,6 +2,11 @@ use std::array::TryFromSliceError;
|
|||
|
||||
use subtle::{Choice, ConstantTimeEq};
|
||||
|
||||
use crate::sapling::{
|
||||
keys::NullifierDerivingKey,
|
||||
spec::{mixing_pedersen_hash, prf_nf},
|
||||
};
|
||||
|
||||
/// Typesafe wrapper for nullifier values.
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Nullifier(pub [u8; 32]);
|
||||
|
@ -14,6 +19,20 @@ impl Nullifier {
|
|||
pub fn to_vec(&self) -> Vec<u8> {
|
||||
self.0.to_vec()
|
||||
}
|
||||
|
||||
/// $DeriveNullifier$.
|
||||
///
|
||||
/// Defined in [Zcash Protocol Spec § 4.16: Note Commitments and Nullifiers][commitmentsandnullifiers].
|
||||
///
|
||||
/// [commitmentsandnullifiers]: https://zips.z.cash/protocol/protocol.pdf#commitmentsandnullifiers
|
||||
pub(super) fn derive(
|
||||
nk: &NullifierDerivingKey,
|
||||
cm: jubjub::SubgroupPoint,
|
||||
position: u64,
|
||||
) -> Self {
|
||||
let rho = mixing_pedersen_hash(cm, position);
|
||||
Nullifier(prf_nf(&nk.0, &rho))
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<[u8]> for Nullifier {
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
//! Helper functions defined in the Zcash Protocol Specification.
|
||||
|
||||
use blake2s_simd::Params as Blake2sParams;
|
||||
use group::GroupEncoding;
|
||||
|
||||
use crate::constants::{NULLIFIER_POSITION_GENERATOR, PRF_NF_PERSONALIZATION};
|
||||
|
||||
/// $MixingPedersenHash$.
|
||||
///
|
||||
/// Defined in [Zcash Protocol Spec § 5.4.1.8: Mixing Pedersen Hash Function][concretemixinghash].
|
||||
///
|
||||
/// [concretemixinghash]: https://zips.z.cash/protocol/protocol.pdf#concretemixinghash
|
||||
pub(crate) fn mixing_pedersen_hash(
|
||||
cm: jubjub::SubgroupPoint,
|
||||
position: u64,
|
||||
) -> jubjub::SubgroupPoint {
|
||||
cm + (NULLIFIER_POSITION_GENERATOR * jubjub::Fr::from(position))
|
||||
}
|
||||
|
||||
/// $PRF^\mathsf{nfSapling}_{nk}(\rho)$
|
||||
///
|
||||
/// Defined in [Zcash Protocol Spec § 5.4.2: Pseudo Random Functions][concreteprfs].
|
||||
///
|
||||
/// [concreteprfs]: https://zips.z.cash/protocol/protocol.pdf#concreteprfs
|
||||
pub(crate) fn prf_nf(nk: &jubjub::SubgroupPoint, rho: &jubjub::SubgroupPoint) -> [u8; 32] {
|
||||
Blake2sParams::new()
|
||||
.hash_length(32)
|
||||
.personal(PRF_NF_PERSONALIZATION)
|
||||
.to_state()
|
||||
.update(&nk.to_bytes())
|
||||
.update(&rho.to_bytes())
|
||||
.finalize()
|
||||
.as_bytes()
|
||||
.try_into()
|
||||
.expect("output length is correct")
|
||||
}
|
Loading…
Reference in New Issue