Sapling value commitment, half done Sapling note commitment

This commit is contained in:
Deirdre Connolly 2020-07-17 02:35:11 -04:00 committed by Deirdre Connolly
parent 823b06b219
commit f64e0c4bc5
3 changed files with 74 additions and 5 deletions

View File

@ -124,7 +124,9 @@ fn jubjub_group_hash(d: [u8; 8], m: &[u8]) -> Option<jubjub::ExtendedPoint> {
///
/// [0]: https://github.com/zcash/librustzcash/blob/master/zcash_primitives/src/jubjub/mod.rs#L409
/// https://zips.z.cash/protocol/protocol.pdf#concretegrouphashjubjub
fn find_group_hash(d: [u8; 8], m: &[u8]) -> jubjub::ExtendedPoint {
// TODO: move common functions like these out of the keys module into
// a more appropriate location
pub fn find_group_hash(d: [u8; 8], m: &[u8]) -> jubjub::ExtendedPoint {
let mut tag = m.to_vec();
let i = tag.len();
tag.push(0u8);

View File

@ -8,7 +8,7 @@ mod commitments;
mod nullifiers;
use crate::{
keys::sapling::{Diversifier, TransmissionKey},
keys::sapling::{diversify_hash, find_group_hash, Diversifier, TransmissionKey},
notes::memo::Memo,
types::amount::{Amount, NonNegative},
};
@ -17,6 +17,11 @@ pub use ciphertexts::{EncryptedCiphertext, OutCiphertext};
pub use commitments::{CommitmentRandomness, NoteCommitment, ValueCommitment};
pub use nullifiers::Nullifier;
///
///
/// https://zips.z.cash/protocol/protocol.pdf#concretepedersenhash
pub fn pedersen_hash_to_point() {}
/// A Note represents that a value is spendable by the recipient who
/// holds the spending key corresponding to a given shielded payment
/// address.
@ -32,9 +37,17 @@ impl Note {
/// Perderson hash constructon, and adding a randomized point on
/// the Jubjub curve.
///
/// WindowedPedersenCommit_r (s) := \
/// PedersenHashToPoint(“Zcash_PH”, s) + [r]FindGroupHash^J^(r)(“Zcash_PH”, “r”)
///
/// NoteCommit^Sapling_rcm (g*_d , pk*_d , v) := \
/// WindowedPedersenCommit_rcm([1; 6] || I2LEBSP_64(v) || g*_d || pk*_d)
///
/// https://zips.z.cash/protocol/protocol.pdf#concretewindowedcommit
pub fn commit(&self) -> NoteCommitment {
unimplemented!()
let g_d = diversify_hash(self.diversifier.0).unwrap();
NoteCommitment::new(g_d, self.transmission_key, self.value)
}
}

View File

@ -1,10 +1,17 @@
use std::{fmt, io};
use rand_core::{CryptoRng, RngCore};
use crate::{
keys::sapling::find_group_hash,
serde_helpers,
serialization::{ReadZcashExt, SerializationError, ZcashDeserialize, ZcashSerialize},
};
// TODO: replace with reference to redjubjub or jubjub when merged and
// exported.
type Scalar = jubjub::Fr;
/// The randomness used in the Pedersen Hash for note commitment.
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct CommitmentRandomness(redjubjub::Randomizer);
@ -38,8 +45,6 @@ impl From<NoteCommitment> for [u8; 32] {
}
impl ZcashSerialize for NoteCommitment {
// The u-coordinate of the note commitment, for the output note
// LEBS2OSP256(cm_u) where cm_u = Extract_J(r)(cm). ???
fn zcash_serialize<W: io::Write>(&self, mut writer: W) -> Result<(), io::Error> {
writer.write_all(&self.0.to_bytes())?;
Ok(())
@ -55,6 +60,26 @@ impl ZcashDeserialize for NoteCommitment {
}
impl NoteCommitment {
/// Generate a new _NoteCommitment_.
///
/// https://zips.z.cash/protocol/protocol.pdf#concretewindowedcommit
#[allow(non_snake_case)]
pub fn new<T>(csprng: &mut T, value_bytes: [u8; 32]) -> Self
where
T: RngCore + CryptoRng,
{
let v = Scalar::from_bytes(&value_bytes).unwrap();
let mut rcv_bytes = [0u8; 32];
csprng.fill_bytes(&mut rcv_bytes);
let rcv = Scalar::from_bytes(&rcv_bytes).unwrap();
let V = find_group_hash(*b"Zcash_cv", b"v");
let R = find_group_hash(*b"Zcash_cv", b"r");
Self::from(V * v + R * rcv)
}
/// Hash Extractor for Jubjub (?)
///
/// https://zips.z.cash/protocol/protocol.pdf#concreteextractorjubjub
@ -86,6 +111,12 @@ impl From<[u8; 32]> for ValueCommitment {
}
}
impl From<jubjub::ExtendedPoint> for ValueCommitment {
fn from(extended_point: jubjub::ExtendedPoint) -> Self {
Self(jubjub::AffinePoint::from(extended_point))
}
}
impl Eq for ValueCommitment {}
impl From<ValueCommitment> for [u8; 32] {
@ -112,3 +143,26 @@ impl ZcashDeserialize for ValueCommitment {
))
}
}
impl ValueCommitment {
/// Generate a new _ValueCommitment_.
///
/// https://zips.z.cash/protocol/protocol.pdf#concretehomomorphiccommit
// TODO: accept an Amount instead?
#[allow(non_snake_case)]
pub fn new<T>(csprng: &mut T, value_bytes: [u8; 32]) -> Self
where
T: RngCore + CryptoRng,
{
let v = Scalar::from_bytes(&value_bytes).unwrap();
let mut rcv_bytes = [0u8; 32];
csprng.fill_bytes(&mut rcv_bytes);
let rcv = Scalar::from_bytes(&rcv_bytes).unwrap();
let V = find_group_hash(*b"Zcash_cv", b"v");
let R = find_group_hash(*b"Zcash_cv", b"r");
Self::from(V * v + R * rcv)
}
}