pedersen_hash_to_point() works, with submethods using bitvec

Also tidy, document
This commit is contained in:
Deirdre Connolly 2020-07-24 20:57:52 -04:00 committed by Deirdre Connolly
parent ada3066e14
commit caef323f9b
6 changed files with 32 additions and 37 deletions

View File

@ -1,4 +1,5 @@
//! Note encryption types.
mod memo;
pub mod sapling;

View File

@ -1,3 +1,5 @@
//! Sprout notes
#![allow(clippy::unit_arg)]
#![allow(dead_code)]
@ -17,11 +19,6 @@ 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.

View File

@ -1,3 +1,5 @@
//! Sapling note and value commitments
use std::{fmt, io};
use bitvec::prelude::*;
@ -14,30 +16,29 @@ use crate::{
// exported.
type Scalar = jubjub::Fr;
pub fn pedersen_hash_to_point(domain: [u8; 8], M: BitVec<Lsb0, u8>) -> jubjub::ExtendedPoint {
#[allow(non_snake_case)]
pub fn pedersen_hash_to_point(domain: [u8; 8], M: &BitVec<Lsb0, u8>) -> jubjub::ExtendedPoint {
// Expects i to be 0-indexed
fn I_i(domain: [u8; 8], i: usize) -> jubjub::ExtendedPoint {
find_group_hash(domain, &i.to_le_bytes())
}
// ⟨Mᵢ⟩
// fn m_i<O, T>(segment: BitSlice<O, T>) -> Scalar
// where
// O: BitOrder,
// T: BitStore,
// {
// let value = segment
// .chunks(3)
// .enumerate()
// .try_fold(0, |acc, (j, chunk)| {
// let mut bits = bits![Lsb0; 0; 3];
// bits.copy_from_slice(chunk);
fn M_i(segment: &BitSlice<Lsb0, u8>) -> Scalar {
let mut m_i = [0u8; 32];
// acc += (1 - 2 * bits[2] as u8) * (1 + bits[0] as u8 + 2 * bits[1] as u8)
// });
for (j, chunk) in segment.chunks(3).enumerate() {
let mut data = [0u8; 3];
let bits = data.bits_mut::<Lsb0>();
bits.copy_from_slice(chunk);
// Scalar::from_bytes(*value.into()).unwrap()
// }
let enc_m_j = (1 - (2 * bits[2] as u8)) * (1 + (bits[0] as u8) + (2 * bits[1] as u8));
m_i[0] += enc_m_j * (1 << (4 * j))
}
Scalar::from_bytes(&m_i).unwrap()
}
let mut result = jubjub::ExtendedPoint::identity();
@ -46,19 +47,7 @@ pub fn pedersen_hash_to_point(domain: [u8; 8], M: BitVec<Lsb0, u8>) -> jubjub::E
//
// https://zips.z.cash/protocol/protocol.pdf#concretepedersenhash
for (i, segment) in M.chunks(189).enumerate() {
let mut m_i = [0u8; 32];
// ⟨Mᵢ⟩
for (j, chunk) in segment.chunks(3).enumerate() {
let bits: &BitSlice<_, _> = [0u8; 3].bits::<Lsb0>();
bits.copy_from_slice(chunk);
let enc_m_j = (1 - (2 * bits[2] as u8)) * (1 + (bits[0] as u8) + (2 * bits[1] as u8));
m_i[0] += enc_m_j * (1 << (4 * j))
}
result += I_i(domain, i) * Scalar::from_bytes(&m_i).unwrap()
result += I_i(domain, i) * M_i(&segment)
}
result
@ -74,7 +63,7 @@ pub fn pedersen_hash_to_point(domain: [u8; 8], M: BitVec<Lsb0, u8>) -> jubjub::E
/// https://zips.z.cash/protocol/protocol.pdf#concretewindowedcommit
pub fn windowed_pedersen_commitment_r<T>(
csprng: &mut T,
s: BitVec<Lsb0, u8>,
s: &BitVec<Lsb0, u8>,
) -> jubjub::ExtendedPoint
where
T: RngCore + CryptoRng,
@ -85,7 +74,7 @@ where
csprng.fill_bytes(&mut r_bytes);
let r = Scalar::from_bytes(&r_bytes).unwrap();
pedersen_hash_to_point(D, s) + find_group_hash(D, b"r") * r
pedersen_hash_to_point(D, &s) + find_group_hash(D, b"r") * r
}
/// The randomness used in the Pedersen Hash for note commitment.
@ -174,7 +163,7 @@ impl NoteCommitment {
s.append(&mut BitVec::<Lsb0, u8>::from_slice(&pk_d_bytes[..]));
s.append(&mut BitVec::<Lsb0, u8>::from_slice(&v_bytes[..]));
Self::from(windowed_pedersen_commitment_r(csprng, s))
Self::from(windowed_pedersen_commitment_r(csprng, &s))
}
/// Hash Extractor for Jubjub (?)

View File

@ -1,3 +1,5 @@
//! Sprout notes
#![allow(clippy::unit_arg)]
#![allow(dead_code)]
@ -39,6 +41,9 @@ pub struct Note {
}
impl Note {
/// NoteCommit_rcm^Sprout(a_pk, v, rho)
///
/// https://zips.z.cash/protocol/protocol.pdf#concretesproutnotecommit
pub fn commit(&self) -> NoteCommitment {
let leading_byte: u8 = 0xB0;
let mut hasher = Sha256::default();

View File

@ -1,2 +1,4 @@
//! Treestate representations for Sprout and Sapling
pub mod note_commitment_tree;
// mod nullifier_set;

View File

@ -22,6 +22,7 @@ impl<C> Amount<C> {
self.0.try_into()
}
/// To little endian byte array
pub fn to_bytes(&self) -> [u8; 8] {
self.0.to_le_bytes()
}