orchard/src/note/commitment.rs

67 lines
1.9 KiB
Rust
Raw Normal View History

2021-03-12 16:04:13 -08:00
use std::iter;
use bitvec::{array::BitArray, order::Lsb0};
use ff::PrimeField;
use pasta_curves::pallas;
use subtle::CtOption;
2021-03-12 16:04:13 -08:00
use crate::{
constants::L_ORCHARD_BASE,
primitives::sinsemilla,
spec::{extract_p, prf_expand, to_scalar},
2021-03-12 16:04:13 -08:00
value::NoteValue,
};
use super::RandomSeed;
pub(super) struct NoteCommitTrapdoor(pallas::Scalar);
impl From<&RandomSeed> for NoteCommitTrapdoor {
fn from(rseed: &RandomSeed) -> Self {
NoteCommitTrapdoor(to_scalar(prf_expand(&rseed.0, &[0x05])))
}
}
/// A commitment to a note.
#[derive(Debug)]
2021-03-15 18:27:08 -07:00
pub struct NoteCommitment(pub(super) pallas::Point);
2021-03-12 16:04:13 -08:00
impl NoteCommitment {
/// $NoteCommit^Orchard$.
///
/// Defined in [Zcash Protocol Spec § 5.4.8.4: Sinsemilla commitments][concretesinsemillacommit].
///
/// [concretesinsemillacommit]: https://zips.z.cash/protocol/nu5.pdf#concretesinsemillacommit
pub(super) fn derive(
g_d: [u8; 32],
pk_d: [u8; 32],
v: NoteValue,
rho: pallas::Base,
psi: pallas::Base,
rcm: NoteCommitTrapdoor,
) -> CtOption<Self> {
2021-03-12 16:04:13 -08:00
let domain = sinsemilla::CommitDomain::new("z.cash:Orchard-NoteCommit");
domain
.commit(
2021-03-12 16:04:13 -08:00
iter::empty()
.chain(BitArray::<Lsb0, _>::new(g_d).iter().by_val())
.chain(BitArray::<Lsb0, _>::new(pk_d).iter().by_val())
.chain(v.to_le_bits().iter().by_val())
.chain(rho.to_le_bits().iter().by_val().take(L_ORCHARD_BASE))
.chain(psi.to_le_bits().iter().by_val().take(L_ORCHARD_BASE)),
&rcm.0,
)
.map(NoteCommitment)
2021-03-12 16:04:13 -08:00
}
}
/// The x-coordinate of the commitment to a note.
2021-04-14 21:14:34 -07:00
#[derive(Clone, Debug)]
pub struct ExtractedNoteCommitment(pub(super) pallas::Base);
impl From<NoteCommitment> for ExtractedNoteCommitment {
fn from(cm: NoteCommitment) -> Self {
ExtractedNoteCommitment(extract_p(&cm.0))
}
}