zebra_chain/sprout/
commitment.rs

1//! Sprout commitment types.
2
3use sha2::{Digest, Sha256};
4
5use crate::fmt::HexDebug;
6
7use super::note::Note;
8
9/// The randomness used in the Pedersen Hash for note commitment.
10#[derive(Copy, Clone, Debug, PartialEq, Eq)]
11#[cfg_attr(
12    any(test, feature = "proptest-impl"),
13    derive(proptest_derive::Arbitrary)
14)]
15pub struct CommitmentRandomness(pub HexDebug<[u8; 32]>);
16
17impl AsRef<[u8]> for CommitmentRandomness {
18    fn as_ref(&self) -> &[u8] {
19        self.0.as_ref()
20    }
21}
22
23/// Note commitments for the output notes.
24#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Eq, Serialize)]
25#[cfg_attr(
26    any(test, feature = "proptest-impl"),
27    derive(proptest_derive::Arbitrary)
28)]
29pub struct NoteCommitment(pub(crate) HexDebug<[u8; 32]>);
30
31impl From<[u8; 32]> for NoteCommitment {
32    fn from(bytes: [u8; 32]) -> Self {
33        Self(bytes.into())
34    }
35}
36
37impl From<Note> for NoteCommitment {
38    /// NoteCommit_rcm^Sprout(a_pk, v, rho)
39    ///
40    /// <https://zips.z.cash/protocol/protocol.pdf#concretesproutnotecommit>
41    fn from(note: Note) -> NoteCommitment {
42        let leading_byte: u8 = 0xB0;
43        let mut hasher = Sha256::default();
44        hasher.update([leading_byte]);
45        hasher.update(note.paying_key);
46        hasher.update(note.value.to_bytes());
47        hasher.update(note.rho);
48        hasher.update(note.rcm);
49
50        let commitment: [u8; 32] = hasher.finalize().into();
51        NoteCommitment(commitment.into())
52    }
53}
54
55impl From<NoteCommitment> for [u8; 32] {
56    fn from(cm: NoteCommitment) -> [u8; 32] {
57        *cm.0
58    }
59}
60
61impl From<&NoteCommitment> for [u8; 32] {
62    fn from(cm: &NoteCommitment) -> [u8; 32] {
63        *cm.0
64    }
65}