From 579f1ed134437a111753d91c4104095eb07d9104 Mon Sep 17 00:00:00 2001 From: Deirdre Connolly Date: Thu, 23 Jul 2020 04:48:50 -0400 Subject: [PATCH] Flesh out windowed_pedersen_commitment_r --- Cargo.lock | 9 +++ zebra-chain/src/notes/sapling/commitments.rs | 79 +++++++++++++------- 2 files changed, 63 insertions(+), 25 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0fcbe58e..e5ea552c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -203,6 +203,15 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +[[package]] +name = "bitmaps" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "031043d04099746d8db04daf1fa424b2bc8bd69d92b25962dcde24da39ab64a2" +dependencies = [ + "typenum", +] + [[package]] name = "bitvec" version = "0.17.4" diff --git a/zebra-chain/src/notes/sapling/commitments.rs b/zebra-chain/src/notes/sapling/commitments.rs index c8b34184..0617759a 100644 --- a/zebra-chain/src/notes/sapling/commitments.rs +++ b/zebra-chain/src/notes/sapling/commitments.rs @@ -1,5 +1,6 @@ use std::{fmt, io}; +use bitvec::prelude::*; use rand_core::{CryptoRng, RngCore}; use crate::{ @@ -13,6 +14,37 @@ use crate::{ // exported. type Scalar = jubjub::Fr; +pub fn pedersen_hash_to_point(D: [u8; 8], M: BitVec) -> jubjub::ExtendedPoint { + // Expects i to be 0-indexed + fn I_i(D: [u8; 8], i: u32) -> jubjub::ExtendedPoint { + find_group_hash(D, &i.to_le_bytes()) + } + + jubjub::ExtendedPoint::identity() +} + +/// Construct a “windowed” Pedersen commitment by reusing a 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”) +/// +/// https://zips.z.cash/protocol/protocol.pdf#concretewindowedcommit +pub fn windowed_pedersen_commitment_r( + csprng: &mut T, + s: BitVec, +) -> jubjub::ExtendedPoint +where + T: RngCore + CryptoRng, +{ + let mut r_bytes = [0u8; 32]; + csprng.fill_bytes(&mut r_bytes); + let r = Scalar::from_bytes(&r_bytes).unwrap(); + + pedersen_hash_to_point(*b"Zcash_PH", s) + find_group_hash(*b"Zcash_PH", b"r") * r +} + /// The randomness used in the Pedersen Hash for note commitment. #[derive(Copy, Clone, Debug, PartialEq)] pub struct CommitmentRandomness(redjubjub::Randomizer); @@ -37,6 +69,12 @@ impl From<[u8; 32]> for NoteCommitment { } } +impl From for NoteCommitment { + fn from(extended_point: jubjub::ExtendedPoint) -> Self { + Self(jubjub::AffinePoint::from(extended_point)) + } +} + impl Eq for NoteCommitment {} impl From for [u8; 32] { @@ -63,6 +101,9 @@ impl ZcashDeserialize for NoteCommitment { impl NoteCommitment { /// Generate a new _NoteCommitment_. /// + /// 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 #[allow(non_snake_case)] pub fn new( @@ -74,35 +115,23 @@ impl NoteCommitment { where T: RngCore + CryptoRng, { - // use bitvec::prelude::*; - // // s as in the argument name for WindowedPedersenCommit_r(s) - // let mut s = BitVec::new(); + // s as in the argument name for WindowedPedersenCommit_r(s) + let mut s: BitVec = BitVec::new(); - // // Prefix - // s.extend([1, 1, 1, 1, 1, 1].iter()); + // Prefix + s.append(&mut bitvec![1; 6]); - // // Jubjub repr_J canonical byte encoding - // // https://zips.z.cash/protocol/protocol.pdf#jubjub - // let g_d_bytes = jubjub::AffinePoint::from(diversifier).to_bytes(); - // let pk_d_bytes = transmission_key.into(); - // let v_bytes = value.to_bytes(); + // Jubjub repr_J canonical byte encoding + // https://zips.z.cash/protocol/protocol.pdf#jubjub + let g_d_bytes = jubjub::AffinePoint::from(diversifier).to_bytes(); + let pk_d_bytes = <[u8; 32]>::from(transmission_key); + let v_bytes = value.to_bytes(); - // // Expects i to be 0-indexed - // fn I_i(D: [u8; 8], i: u32) -> jubjub::ExtendedPoint { - // find_group_hash(D, i.to_le_bytes()) - // } - // // let v = Scalar::from_bytes(&value_bytes).unwrap(); + s.append(&mut BitVec::::from_slice(&g_d_bytes[..])); + s.append(&mut BitVec::::from_slice(&pk_d_bytes[..])); + s.append(&mut BitVec::::from_slice(&v_bytes[..])); - // // 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) - - unimplemented!() + Self::from(windowed_pedersen_commitment_r(csprng, s)) } /// Hash Extractor for Jubjub (?)