sapling_crypto/note/
nullifier.rs1use alloc::fmt;
2use alloc::vec::Vec;
3use core::array::TryFromSliceError;
4
5use subtle::{Choice, ConstantTimeEq};
6
7use super::NoteCommitment;
8use crate::{
9 keys::NullifierDerivingKey,
10 spec::{mixing_pedersen_hash, prf_nf},
11};
12
13#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
15pub struct Nullifier(pub [u8; 32]);
16
17impl fmt::Debug for Nullifier {
18 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
19 f.debug_tuple("Nullifier")
20 .field(&hex::encode(self.0))
21 .finish()
22 }
23}
24
25impl Nullifier {
26 pub fn from_slice(bytes: &[u8]) -> Result<Nullifier, TryFromSliceError> {
27 bytes.try_into().map(Nullifier)
28 }
29
30 pub fn to_vec(&self) -> Vec<u8> {
31 self.0.to_vec()
32 }
33
34 pub(super) fn derive(nk: &NullifierDerivingKey, cm: NoteCommitment, position: u64) -> Self {
40 let rho = mixing_pedersen_hash(cm.inner(), position);
41 Nullifier(prf_nf(&nk.0, &rho))
42 }
43}
44
45impl AsRef<[u8]> for Nullifier {
46 fn as_ref(&self) -> &[u8] {
47 &self.0
48 }
49}
50
51impl ConstantTimeEq for Nullifier {
52 fn ct_eq(&self, other: &Self) -> Choice {
53 self.0.ct_eq(&other.0)
54 }
55}