Sapling value commitment, half done Sapling note commitment
This commit is contained in:
parent
823b06b219
commit
f64e0c4bc5
|
@ -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
|
/// [0]: https://github.com/zcash/librustzcash/blob/master/zcash_primitives/src/jubjub/mod.rs#L409
|
||||||
/// https://zips.z.cash/protocol/protocol.pdf#concretegrouphashjubjub
|
/// 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 mut tag = m.to_vec();
|
||||||
let i = tag.len();
|
let i = tag.len();
|
||||||
tag.push(0u8);
|
tag.push(0u8);
|
||||||
|
|
|
@ -8,7 +8,7 @@ mod commitments;
|
||||||
mod nullifiers;
|
mod nullifiers;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
keys::sapling::{Diversifier, TransmissionKey},
|
keys::sapling::{diversify_hash, find_group_hash, Diversifier, TransmissionKey},
|
||||||
notes::memo::Memo,
|
notes::memo::Memo,
|
||||||
types::amount::{Amount, NonNegative},
|
types::amount::{Amount, NonNegative},
|
||||||
};
|
};
|
||||||
|
@ -17,6 +17,11 @@ pub use ciphertexts::{EncryptedCiphertext, OutCiphertext};
|
||||||
pub use commitments::{CommitmentRandomness, NoteCommitment, ValueCommitment};
|
pub use commitments::{CommitmentRandomness, NoteCommitment, ValueCommitment};
|
||||||
pub use nullifiers::Nullifier;
|
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
|
/// A Note represents that a value is spendable by the recipient who
|
||||||
/// holds the spending key corresponding to a given shielded payment
|
/// holds the spending key corresponding to a given shielded payment
|
||||||
/// address.
|
/// address.
|
||||||
|
@ -32,9 +37,17 @@ impl Note {
|
||||||
/// Perderson hash constructon, and adding a randomized point on
|
/// Perderson hash constructon, and adding a randomized point on
|
||||||
/// the Jubjub curve.
|
/// 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
|
/// https://zips.z.cash/protocol/protocol.pdf#concretewindowedcommit
|
||||||
pub fn commit(&self) -> NoteCommitment {
|
pub fn commit(&self) -> NoteCommitment {
|
||||||
unimplemented!()
|
let g_d = diversify_hash(self.diversifier.0).unwrap();
|
||||||
|
|
||||||
|
NoteCommitment::new(g_d, self.transmission_key, self.value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,17 @@
|
||||||
use std::{fmt, io};
|
use std::{fmt, io};
|
||||||
|
|
||||||
|
use rand_core::{CryptoRng, RngCore};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
keys::sapling::find_group_hash,
|
||||||
serde_helpers,
|
serde_helpers,
|
||||||
serialization::{ReadZcashExt, SerializationError, ZcashDeserialize, ZcashSerialize},
|
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.
|
/// The randomness used in the Pedersen Hash for note commitment.
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||||
pub struct CommitmentRandomness(redjubjub::Randomizer);
|
pub struct CommitmentRandomness(redjubjub::Randomizer);
|
||||||
|
@ -38,8 +45,6 @@ impl From<NoteCommitment> for [u8; 32] {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ZcashSerialize for NoteCommitment {
|
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> {
|
fn zcash_serialize<W: io::Write>(&self, mut writer: W) -> Result<(), io::Error> {
|
||||||
writer.write_all(&self.0.to_bytes())?;
|
writer.write_all(&self.0.to_bytes())?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -55,6 +60,26 @@ impl ZcashDeserialize for NoteCommitment {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl 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 (?)
|
/// Hash Extractor for Jubjub (?)
|
||||||
///
|
///
|
||||||
/// https://zips.z.cash/protocol/protocol.pdf#concreteextractorjubjub
|
/// 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 Eq for ValueCommitment {}
|
||||||
|
|
||||||
impl From<ValueCommitment> for [u8; 32] {
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue