2021-03-12 16:04:13 -08:00
|
|
|
use std::iter;
|
|
|
|
|
|
|
|
use bitvec::{array::BitArray, order::Lsb0};
|
|
|
|
use ff::PrimeField;
|
|
|
|
use pasta_curves::pallas;
|
2021-04-19 15:05:56 -07:00
|
|
|
use subtle::CtOption;
|
2021-03-12 16:04:13 -08:00
|
|
|
|
|
|
|
use crate::{
|
|
|
|
constants::L_ORCHARD_BASE,
|
|
|
|
primitives::sinsemilla,
|
2021-04-19 15:26:58 -07:00
|
|
|
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,
|
2021-04-19 15:05:56 -07:00
|
|
|
) -> CtOption<Self> {
|
2021-03-12 16:04:13 -08:00
|
|
|
let domain = sinsemilla::CommitDomain::new("z.cash:Orchard-NoteCommit");
|
2021-04-19 15:05:56 -07:00
|
|
|
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,
|
2021-04-19 15:05:56 -07:00
|
|
|
)
|
|
|
|
.map(NoteCommitment)
|
2021-03-12 16:04:13 -08:00
|
|
|
}
|
|
|
|
}
|
2021-04-19 15:26:58 -07:00
|
|
|
|
|
|
|
/// The x-coordinate of the commitment to a note.
|
2021-04-14 21:14:34 -07:00
|
|
|
#[derive(Clone, Debug)]
|
2021-04-19 15:26:58 -07:00
|
|
|
pub struct ExtractedNoteCommitment(pub(super) pallas::Base);
|
|
|
|
|
|
|
|
impl From<NoteCommitment> for ExtractedNoteCommitment {
|
|
|
|
fn from(cm: NoteCommitment) -> Self {
|
|
|
|
ExtractedNoteCommitment(extract_p(&cm.0))
|
|
|
|
}
|
|
|
|
}
|