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 NoteCommitment {
32    /// Return the bytes in big-endian byte order as required
33    /// by RPCs such as `getrawtransaction`.
34    pub fn bytes_in_display_order(&self) -> [u8; 32] {
35        let mut root: [u8; 32] = self.into();
36        root.reverse();
37        root
38    }
39}
40
41impl From<[u8; 32]> for NoteCommitment {
42    fn from(bytes: [u8; 32]) -> Self {
43        Self(bytes.into())
44    }
45}
46
47impl From<Note> for NoteCommitment {
48    /// NoteCommit_rcm^Sprout(a_pk, v, rho)
49    ///
50    /// <https://zips.z.cash/protocol/protocol.pdf#concretesproutnotecommit>
51    fn from(note: Note) -> NoteCommitment {
52        let leading_byte: u8 = 0xB0;
53        let mut hasher = Sha256::default();
54        hasher.update([leading_byte]);
55        hasher.update(note.paying_key);
56        hasher.update(note.value.to_bytes());
57        hasher.update(note.rho);
58        hasher.update(note.rcm);
59
60        let commitment: [u8; 32] = hasher.finalize().into();
61        NoteCommitment(commitment.into())
62    }
63}
64
65impl From<NoteCommitment> for [u8; 32] {
66    fn from(cm: NoteCommitment) -> [u8; 32] {
67        *cm.0
68    }
69}
70
71impl From<&NoteCommitment> for [u8; 32] {
72    fn from(cm: &NoteCommitment) -> [u8; 32] {
73        *cm.0
74    }
75}