sapling_crypto/note/
commitment.rs1use core::iter;
2
3use bitvec::{array::BitArray, order::Lsb0};
4use group::ff::PrimeField;
5use subtle::{ConstantTimeEq, CtOption};
6
7use crate::{
8 pedersen_hash::Personalization,
9 spec::{extract_p, windowed_pedersen_commit},
10 value::NoteValue,
11};
12
13#[derive(Clone, Debug)]
15pub(crate) struct NoteCommitTrapdoor(pub(super) jubjub::Fr);
16
17#[derive(Clone, Debug)]
19pub struct NoteCommitment(jubjub::SubgroupPoint);
20
21impl NoteCommitment {
22 pub(crate) fn inner(&self) -> jubjub::SubgroupPoint {
23 self.0
24 }
25}
26
27impl NoteCommitment {
28 #[cfg(feature = "temporary-zcashd")]
30 pub fn temporary_zcashd_derive(
31 g_d: [u8; 32],
32 pk_d: [u8; 32],
33 v: NoteValue,
34 rcm: jubjub::Fr,
35 ) -> Self {
36 Self::derive(g_d, pk_d, v, NoteCommitTrapdoor(rcm))
37 }
38
39 pub(super) fn derive(
45 g_d: [u8; 32],
46 pk_d: [u8; 32],
47 v: NoteValue,
48 rcm: NoteCommitTrapdoor,
49 ) -> Self {
50 NoteCommitment(windowed_pedersen_commit(
51 Personalization::NoteCommitment,
52 iter::empty()
53 .chain(v.to_le_bits().iter().by_vals())
54 .chain(BitArray::<_, Lsb0>::new(g_d).iter().by_vals())
55 .chain(BitArray::<_, Lsb0>::new(pk_d).iter().by_vals()),
56 rcm.0,
57 ))
58 }
59}
60
61#[derive(Copy, Clone, Debug)]
63pub struct ExtractedNoteCommitment(pub(super) bls12_381::Scalar);
64
65impl ExtractedNoteCommitment {
66 pub fn from_bytes(bytes: &[u8; 32]) -> CtOption<Self> {
73 bls12_381::Scalar::from_repr(*bytes).map(ExtractedNoteCommitment)
74 }
75
76 pub fn to_bytes(self) -> [u8; 32] {
78 self.0.to_repr()
79 }
80
81 pub(crate) fn inner(&self) -> jubjub::Base {
82 self.0
83 }
84}
85
86impl From<NoteCommitment> for ExtractedNoteCommitment {
87 fn from(cm: NoteCommitment) -> Self {
88 ExtractedNoteCommitment(extract_p(&cm.0))
89 }
90}
91
92impl From<&ExtractedNoteCommitment> for [u8; 32] {
93 fn from(cmu: &ExtractedNoteCommitment) -> Self {
94 cmu.to_bytes()
95 }
96}
97
98impl ConstantTimeEq for ExtractedNoteCommitment {
99 fn ct_eq(&self, other: &Self) -> subtle::Choice {
100 self.0.ct_eq(&other.0)
101 }
102}
103
104impl PartialEq for ExtractedNoteCommitment {
105 fn eq(&self, other: &Self) -> bool {
106 self.ct_eq(other).into()
107 }
108}
109
110impl Eq for ExtractedNoteCommitment {}