Compute pedersen hash to point in scalar field
This commit is contained in:
parent
8ececebea7
commit
14d502a54b
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod arbitrary;
|
mod arbitrary;
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test_vectors;
|
||||||
|
|
||||||
use std::{fmt, io};
|
use std::{fmt, io};
|
||||||
|
|
||||||
|
@ -52,21 +54,48 @@ pub fn pedersen_hash_to_point(domain: [u8; 8], M: &BitVec<Lsb0, u8>) -> jubjub::
|
||||||
find_group_hash(domain, &i.to_le_bytes())
|
find_group_hash(domain, &i.to_le_bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
// ⟨Mᵢ⟩
|
/// ⟨Mᵢ⟩
|
||||||
|
///
|
||||||
|
/// Σ j={0,k-1}: (1 - 2x₂)⋅(1 + x₀ + 2x₁)⋅2^(4⋅j)
|
||||||
|
// XXX: Are internal functions doc'd?
|
||||||
|
//
|
||||||
|
// This is less efficient than it could be so that it can match the math
|
||||||
|
// closely.
|
||||||
fn M_i(segment: &BitSlice<Lsb0, u8>) -> jubjub::Fr {
|
fn M_i(segment: &BitSlice<Lsb0, u8>) -> jubjub::Fr {
|
||||||
let mut m_i = [0u8; 32];
|
let mut m_i = jubjub::Fr::zero();
|
||||||
|
|
||||||
for (j, chunk) in segment.chunks(3).enumerate() {
|
for (j, chunk) in segment.chunks(3).enumerate() {
|
||||||
let mut data = [0u8; 3];
|
// Pad each chunk with zeros.
|
||||||
let bits = data.bits_mut::<Lsb0>();
|
let mut store = 0u8;
|
||||||
bits.copy_from_slice(chunk);
|
let bits = store.bits_mut::<Lsb0>();
|
||||||
|
chunk
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.for_each(|(i, bit)| bits.set(i, *bit));
|
||||||
|
|
||||||
let enc_m_j = (1 - (2 * bits[2] as u8)) * (1 + (bits[0] as u8) + (2 * bits[1] as u8));
|
let mut tmp = jubjub::Fr::one();
|
||||||
|
|
||||||
m_i[0] += enc_m_j * (1 << (4 * j))
|
if bits[0] {
|
||||||
|
tmp += &jubjub::Fr::one();
|
||||||
|
}
|
||||||
|
|
||||||
|
if bits[1] {
|
||||||
|
tmp += &jubjub::Fr::one().double();
|
||||||
|
}
|
||||||
|
|
||||||
|
if bits[2] {
|
||||||
|
tmp -= tmp.double();
|
||||||
|
}
|
||||||
|
|
||||||
|
// tmp * 2^(4*j)
|
||||||
|
if j > 0 {
|
||||||
|
tmp *= (1..(4 * j)).fold(jubjub::Fr::one(), |acc, _| acc.double());
|
||||||
|
}
|
||||||
|
|
||||||
|
m_i += tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
jubjub::Fr::from_bytes(&m_i).unwrap()
|
m_i
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut result = jubjub::ExtendedPoint::identity();
|
let mut result = jubjub::ExtendedPoint::identity();
|
||||||
|
@ -98,8 +127,8 @@ pub fn mixing_pedersen_hash(P: jubjub::ExtendedPoint, x: jubjub::Fr) -> jubjub::
|
||||||
P + find_group_hash(J, b"") * x
|
P + find_group_hash(J, b"") * x
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Construct a 'windowed' Pedersen commitment by reusing a Perderson hash
|
/// Construct a 'windowed' Pedersen commitment by reusing a Pederson hash
|
||||||
/// constructon, and adding a randomized point on the Jubjub curve.
|
/// construction, and adding a randomized point on the Jubjub curve.
|
||||||
///
|
///
|
||||||
/// WindowedPedersenCommit_r (s) := \
|
/// WindowedPedersenCommit_r (s) := \
|
||||||
/// PedersenHashToPoint(“Zcash_PH”, s) + [r]FindGroupHash^J^(r)(“Zcash_PH”, “r”)
|
/// PedersenHashToPoint(“Zcash_PH”, s) + [r]FindGroupHash^J^(r)(“Zcash_PH”, “r”)
|
||||||
|
@ -289,3 +318,33 @@ impl ValueCommitment {
|
||||||
Self::from(V * v + R * rcv)
|
Self::from(V * v + R * rcv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
// use crate::commitments::sapling::test_vectors::TEST_VECTORS;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn pedersen_hash_to_point_test_vectors() {
|
||||||
|
const D: [u8; 8] = *b"Zcash_PH";
|
||||||
|
|
||||||
|
let result =
|
||||||
|
pedersen_hash_to_point(D, &BitVec::<Lsb0, u8>::from_vec(vec![1, 1, 1, 1, 1, 1]));
|
||||||
|
|
||||||
|
let point = jubjub::AffinePoint::from(result);
|
||||||
|
|
||||||
|
println!("{:?}", point);
|
||||||
|
|
||||||
|
//println!("u: ");
|
||||||
|
|
||||||
|
// for test_vector in TEST_VECTORS.iter() {
|
||||||
|
// let result = pedersen_hash_to_point(
|
||||||
|
// D,
|
||||||
|
// &BitVec::<Lsb0, u8>::from_vec(test_vector.input_bits.clone()),
|
||||||
|
// );
|
||||||
|
|
||||||
|
// assert_eq!(jubjub::AffinePoint::from(result), test_vector.hash_point);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue