mirror of
https://github.com/arnaucube/fri-commitment.git
synced 2026-01-12 08:51:32 +01:00
Abstract hash function, upgrade to arkworks v0.4.0
This commit is contained in:
21
Cargo.toml
21
Cargo.toml
@@ -9,18 +9,13 @@ repository = "https://github.com/arnaucube/fri-commitment"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
ark-std = "0.3.0"
|
ark-std = "0.4.0"
|
||||||
ark-ff = "0.3.0"
|
ark-ff = "0.4.0"
|
||||||
ark-poly = "0.3.0"
|
ark-poly = "0.4.0"
|
||||||
ark-bn254 = { version = "^0.3.0", default-features = false }
|
ark-bn254 = { version = "0.4.0", default-features = false }
|
||||||
ark-ed-on-bn254 = { version = "^0.3.0", default-features = true }
|
ark-ed-on-bn254 = { version = "0.4.0", default-features = true }
|
||||||
ark-crypto-primitives = { version = "^0.3.0", default-features = true }
|
ark-crypto-primitives = { version = "0.4.0", default-features = true }
|
||||||
|
ark-serialize = { version = "0.4.0", default-features = false, features = [ "derive" ] }
|
||||||
rand = { version = "0.8", features = [ "std", "std_rng" ] }
|
rand = { version = "0.8", features = [ "std", "std_rng" ] }
|
||||||
|
sha3 = "0.10.6"
|
||||||
# poseidon related
|
|
||||||
arkworks-utils = { git = "https://github.com/aragonzkresearch/arkworks-gadgets", name="arkworks-utils", features=["poseidon_bn254_x5_4"] }
|
|
||||||
arkworks-native-gadgets = { git = "https://github.com/aragonzkresearch/arkworks-gadgets", name="arkworks-native-gadgets"}
|
|
||||||
|
|
||||||
# transcript related
|
|
||||||
merlin = { version = "3.0.0" }
|
merlin = { version = "3.0.0" }
|
||||||
ark-serialize = { version = "^0.3.0", default-features = false, features = [ "derive" ] }
|
|
||||||
|
|||||||
25
src/lib.rs
25
src/lib.rs
@@ -3,13 +3,13 @@
|
|||||||
#![allow(non_upper_case_globals)]
|
#![allow(non_upper_case_globals)]
|
||||||
|
|
||||||
pub mod merkletree;
|
pub mod merkletree;
|
||||||
use merkletree::MerkleTreePoseidon as MT;
|
use merkletree::{Hash, MerkleTree};
|
||||||
pub mod transcript;
|
pub mod transcript;
|
||||||
use transcript::Transcript;
|
use transcript::Transcript;
|
||||||
|
|
||||||
use ark_ff::PrimeField;
|
use ark_ff::PrimeField;
|
||||||
use ark_poly::{
|
use ark_poly::{
|
||||||
univariate::DensePolynomial, EvaluationDomain, GeneralEvaluationDomain, UVPolynomial,
|
univariate::DensePolynomial, DenseUVPolynomial, EvaluationDomain, GeneralEvaluationDomain,
|
||||||
};
|
};
|
||||||
|
|
||||||
use ark_std::cfg_into_iter;
|
use ark_std::cfg_into_iter;
|
||||||
@@ -19,20 +19,22 @@ use ark_std::ops::Mul;
|
|||||||
// rho^-1
|
// rho^-1
|
||||||
const rho1: usize = 8; // WIP
|
const rho1: usize = 8; // WIP
|
||||||
|
|
||||||
pub struct FRI_LDT<F: PrimeField, P: UVPolynomial<F>> {
|
pub struct FRI_LDT<F: PrimeField, P: DenseUVPolynomial<F>, H: Hash<F>> {
|
||||||
_f: PhantomData<F>,
|
_f: PhantomData<F>,
|
||||||
_poly: PhantomData<P>,
|
_poly: PhantomData<P>,
|
||||||
|
_h: PhantomData<H>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: PrimeField, P: UVPolynomial<F>> FRI_LDT<F, P> {
|
impl<F: PrimeField, P: DenseUVPolynomial<F>, H: Hash<F>> FRI_LDT<F, P, H> {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
_f: PhantomData,
|
_f: PhantomData,
|
||||||
_poly: PhantomData,
|
_poly: PhantomData,
|
||||||
|
_h: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn split(p: &P) -> (P, P) {
|
fn split(p: &P) -> (P, P) {
|
||||||
// let d = p.degree() + 1;
|
// let d = p.degree() + 1;
|
||||||
let d = p.coeffs().len();
|
let d = p.coeffs().len();
|
||||||
if (d != 0) && (d & (d - 1) != 0) {
|
if (d != 0) && (d & (d - 1) != 0) {
|
||||||
@@ -57,7 +59,7 @@ impl<F: PrimeField, P: UVPolynomial<F>> FRI_LDT<F, P> {
|
|||||||
|
|
||||||
let d = p.degree();
|
let d = p.degree();
|
||||||
let mut commitments: Vec<F> = Vec::new();
|
let mut commitments: Vec<F> = Vec::new();
|
||||||
let mut mts: Vec<MT<F>> = Vec::new();
|
let mut mts: Vec<MerkleTree<F, H>> = Vec::new();
|
||||||
|
|
||||||
// f_0(x) = fL_0(x^2) + x fR_0(x^2)
|
// f_0(x) = fL_0(x^2) + x fR_0(x^2)
|
||||||
let mut f_i1 = p.clone();
|
let mut f_i1 = p.clone();
|
||||||
@@ -85,8 +87,8 @@ impl<F: PrimeField, P: UVPolynomial<F>> FRI_LDT<F, P> {
|
|||||||
.map(|k| f_i1.evaluate(&eval_sub_domain.element(k)))
|
.map(|k| f_i1.evaluate(&eval_sub_domain.element(k)))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
// commit to f_{i+1}(x) = fL_i(x) + alpha_i * fR_i(x)
|
// commit to f_{i+1}(x) = fL_i(x) + alpha_i * fR_i(x), commit to the evaluation domain
|
||||||
let (cm_i, mt_i) = MT::commit(&subdomain_evaluations); // commit to the evaluation domain instead
|
let (cm_i, mt_i) = MerkleTree::<F, H>::commit(&subdomain_evaluations);
|
||||||
commitments.push(cm_i);
|
commitments.push(cm_i);
|
||||||
mts.push(mt_i);
|
mts.push(mt_i);
|
||||||
transcript.add(b"root_i", &cm_i);
|
transcript.add(b"root_i", &cm_i);
|
||||||
@@ -181,7 +183,7 @@ impl<F: PrimeField, P: UVPolynomial<F>> FRI_LDT<F, P> {
|
|||||||
transcript.add(b"f_i(-z^{2^i})", &evals[i + 1]);
|
transcript.add(b"f_i(-z^{2^i})", &evals[i + 1]);
|
||||||
|
|
||||||
// check commitment opening
|
// check commitment opening
|
||||||
if !MT::verify(
|
if !MerkleTree::<F, H>::verify(
|
||||||
commitments[i_z],
|
commitments[i_z],
|
||||||
F::from(z_pos as u32),
|
F::from(z_pos as u32),
|
||||||
evals[i],
|
evals[i],
|
||||||
@@ -220,6 +222,7 @@ mod tests {
|
|||||||
use ark_poly::univariate::DensePolynomial;
|
use ark_poly::univariate::DensePolynomial;
|
||||||
use ark_poly::Polynomial;
|
use ark_poly::Polynomial;
|
||||||
use ark_std::log2;
|
use ark_std::log2;
|
||||||
|
use merkletree::Keccak256Hash;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_split() {
|
fn test_split() {
|
||||||
@@ -228,7 +231,7 @@ mod tests {
|
|||||||
let p = DensePolynomial::<Fr>::rand(deg, &mut rng);
|
let p = DensePolynomial::<Fr>::rand(deg, &mut rng);
|
||||||
assert_eq!(p.degree(), deg);
|
assert_eq!(p.degree(), deg);
|
||||||
|
|
||||||
type FRID = FRI_LDT<Fr, DensePolynomial<Fr>>;
|
type FRID = FRI_LDT<Fr, DensePolynomial<Fr>, Keccak256Hash<Fr>>;
|
||||||
let (pL, pR) = FRID::split(&p);
|
let (pL, pR) = FRID::split(&p);
|
||||||
|
|
||||||
// check that f(z) == fL(x^2) + x * fR(x^2), for a rand z
|
// check that f(z) == fL(x^2) + x * fR(x^2), for a rand z
|
||||||
@@ -248,7 +251,7 @@ mod tests {
|
|||||||
assert_eq!(p.degree(), deg);
|
assert_eq!(p.degree(), deg);
|
||||||
// println!("p {:?}", p);
|
// println!("p {:?}", p);
|
||||||
|
|
||||||
type FRID = FRI_LDT<Fr, DensePolynomial<Fr>>;
|
type FRID = FRI_LDT<Fr, DensePolynomial<Fr>, Keccak256Hash<Fr>>;
|
||||||
|
|
||||||
let (commitments, mtproofs, evals, constvals) = FRID::prove(&p);
|
let (commitments, mtproofs, evals, constvals) = FRID::prove(&p);
|
||||||
// commitments contains the commitments to each f_0, f_1, ..., f_n, with n=log2(d)
|
// commitments contains the commitments to each f_0, f_1, ..., f_n, with n=log2(d)
|
||||||
|
|||||||
@@ -4,40 +4,59 @@
|
|||||||
// https://github.com/vocdoni/arbo).
|
// https://github.com/vocdoni/arbo).
|
||||||
|
|
||||||
use ark_ff::{BigInteger, PrimeField};
|
use ark_ff::{BigInteger, PrimeField};
|
||||||
|
use ark_serialize::CanonicalSerialize;
|
||||||
use ark_std::log2;
|
use ark_std::log2;
|
||||||
use arkworks_native_gadgets::poseidon;
|
use ark_std::marker::PhantomData;
|
||||||
use arkworks_native_gadgets::poseidon::FieldHasher;
|
use sha3::{Digest, Keccak256};
|
||||||
use arkworks_utils::{
|
|
||||||
bytes_matrix_to_f, bytes_vec_to_f, poseidon_params::setup_poseidon_params, Curve,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub struct Params<F: PrimeField> {
|
// abstraction to set the hash function used
|
||||||
pub poseidon_hash: poseidon::Poseidon<F>,
|
pub trait Hash<F>: Clone {
|
||||||
|
fn hash(_in: &[F]) -> F;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
pub struct Keccak256Hash<F: PrimeField> {
|
||||||
|
phantom: PhantomData<F>,
|
||||||
|
}
|
||||||
|
impl<F: PrimeField> Hash<F> for Keccak256Hash<F> {
|
||||||
|
fn hash(_in: &[F]) -> F {
|
||||||
|
let mut buf = vec![];
|
||||||
|
_in.serialize_uncompressed(&mut buf).unwrap();
|
||||||
|
|
||||||
|
let mut h = Keccak256::default();
|
||||||
|
h.update(buf);
|
||||||
|
let r = h.finalize();
|
||||||
|
let out = F::from_le_bytes_mod_order(&r);
|
||||||
|
out
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Node<F: PrimeField> {
|
pub struct Node<F: PrimeField, H: Hash<F>> {
|
||||||
|
phantom: PhantomData<H>,
|
||||||
hash: F,
|
hash: F,
|
||||||
left: Option<Box<Node<F>>>,
|
left: Option<Box<Node<F, H>>>,
|
||||||
right: Option<Box<Node<F>>>,
|
right: Option<Box<Node<F, H>>>,
|
||||||
value: Option<F>,
|
value: Option<F>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: PrimeField> Node<F> {
|
impl<F: PrimeField, H: Hash<F>> Node<F, H> {
|
||||||
pub fn new_leaf(params: &Params<F>, v: F) -> Self {
|
pub fn new_leaf(v: F) -> Self {
|
||||||
let h = params.poseidon_hash.hash(&[v]).unwrap();
|
let h = H::hash(&[v]);
|
||||||
Self {
|
Self {
|
||||||
|
phantom: PhantomData::<H>,
|
||||||
hash: h,
|
hash: h,
|
||||||
left: None,
|
left: None,
|
||||||
right: None,
|
right: None,
|
||||||
value: Some(v),
|
value: Some(v),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn new_node(params: &Params<F>, l: Self, r: Self) -> Self {
|
pub fn new_node(l: Self, r: Self) -> Self {
|
||||||
let left = Box::new(l);
|
let left = Box::new(l);
|
||||||
let right = Box::new(r);
|
let right = Box::new(r);
|
||||||
let hash = params.poseidon_hash.hash(&[left.hash, right.hash]).unwrap();
|
let hash = H::hash(&[left.hash, right.hash]);
|
||||||
Self {
|
Self {
|
||||||
|
phantom: PhantomData::<H>,
|
||||||
hash,
|
hash,
|
||||||
left: Some(left),
|
left: Some(left),
|
||||||
right: Some(right),
|
right: Some(right),
|
||||||
@@ -46,40 +65,39 @@ impl<F: PrimeField> Node<F> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct MerkleTree<F: PrimeField> {
|
pub struct MerkleTree<F: PrimeField, H: Hash<F>> {
|
||||||
pub root: Node<F>,
|
pub root: Node<F, H>,
|
||||||
nlevels: u32,
|
nlevels: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: PrimeField> MerkleTree<F> {
|
impl<F: PrimeField, H: Hash<F>> MerkleTree<F, H> {
|
||||||
pub fn setup(poseidon_hash: &poseidon::Poseidon<F>) -> Params<F> {
|
pub fn commit(values: &[F]) -> (F, Self) {
|
||||||
Params {
|
|
||||||
poseidon_hash: poseidon_hash.clone(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn new(params: &Params<F>, values: Vec<F>) -> Self {
|
|
||||||
// for the moment assume that values length is a power of 2.
|
// for the moment assume that values length is a power of 2.
|
||||||
if (values.len() != 0) && (values.len() & (values.len() - 1) != 0) {
|
if (values.len() != 0) && (values.len() & (values.len() - 1) != 0) {
|
||||||
panic!("values.len() should be a power of 2");
|
panic!("values.len() should be a power of 2");
|
||||||
}
|
}
|
||||||
|
|
||||||
// prepare the leafs
|
// prepare the leafs
|
||||||
let mut leaf_nodes: Vec<Node<F>> = Vec::new();
|
let mut leaf_nodes: Vec<Node<F, H>> = Vec::new();
|
||||||
for i in 0..values.len() {
|
for i in 0..values.len() {
|
||||||
let node = Node::<F>::new_leaf(¶ms, values[i]);
|
let node = Node::<F, H>::new_leaf(values[i]);
|
||||||
leaf_nodes.push(node);
|
leaf_nodes.push(node);
|
||||||
}
|
}
|
||||||
// go up from the leafs to the root
|
// go up from the leafs to the root
|
||||||
let top_nodes = Self::up_from_nodes(¶ms, leaf_nodes);
|
let top_nodes = Self::up_from_nodes(leaf_nodes);
|
||||||
|
|
||||||
|
(
|
||||||
|
top_nodes[0].hash,
|
||||||
Self {
|
Self {
|
||||||
root: top_nodes[0].clone(),
|
root: top_nodes[0].clone(),
|
||||||
nlevels: log2(values.len()),
|
nlevels: log2(values.len()),
|
||||||
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
fn up_from_nodes(nodes: Vec<Node<F, H>>) -> Vec<Node<F, H>> {
|
||||||
fn up_from_nodes(params: &Params<F>, nodes: Vec<Node<F>>) -> Vec<Node<F>> {
|
|
||||||
if nodes.len() == 0 {
|
if nodes.len() == 0 {
|
||||||
return [Node::<F> {
|
return [Node::<F, H> {
|
||||||
|
phantom: PhantomData::<H>,
|
||||||
hash: F::from(0_u32),
|
hash: F::from(0_u32),
|
||||||
left: None,
|
left: None,
|
||||||
right: None,
|
right: None,
|
||||||
@@ -90,22 +108,22 @@ impl<F: PrimeField> MerkleTree<F> {
|
|||||||
if nodes.len() == 1 {
|
if nodes.len() == 1 {
|
||||||
return nodes;
|
return nodes;
|
||||||
}
|
}
|
||||||
let mut next_level_nodes: Vec<Node<F>> = Vec::new();
|
let mut next_level_nodes: Vec<Node<F, H>> = Vec::new();
|
||||||
for i in (0..nodes.len()).step_by(2) {
|
for i in (0..nodes.len()).step_by(2) {
|
||||||
let node = Node::<F>::new_node(¶ms, nodes[i].clone(), nodes[i + 1].clone());
|
let node = Node::<F, H>::new_node(nodes[i].clone(), nodes[i + 1].clone());
|
||||||
next_level_nodes.push(node);
|
next_level_nodes.push(node);
|
||||||
}
|
}
|
||||||
return Self::up_from_nodes(params, next_level_nodes);
|
return Self::up_from_nodes(next_level_nodes);
|
||||||
}
|
}
|
||||||
fn get_path(num_levels: u32, value: F) -> Vec<bool> {
|
fn get_path(num_levels: u32, value: F) -> Vec<bool> {
|
||||||
let value_bytes = value.into_repr().to_bytes_le();
|
let value_bytes = value.into_bigint().to_bytes_le();
|
||||||
let mut path = Vec::new();
|
let mut path = Vec::new();
|
||||||
for i in 0..num_levels {
|
for i in 0..num_levels {
|
||||||
path.push(value_bytes[(i / 8) as usize] & (1 << (i % 8)) != 0);
|
path.push(value_bytes[(i / 8) as usize] & (1 << (i % 8)) != 0);
|
||||||
}
|
}
|
||||||
path
|
path
|
||||||
}
|
}
|
||||||
pub fn gen_proof(&self, index: F) -> Vec<F> {
|
pub fn open(&self, index: F) -> Vec<F> {
|
||||||
// start from root, and go down to the index, while getting the siblings at each level
|
// start from root, and go down to the index, while getting the siblings at each level
|
||||||
let path = Self::get_path(self.nlevels, index);
|
let path = Self::get_path(self.nlevels, index);
|
||||||
// reverse path as we're going from up to down
|
// reverse path as we're going from up to down
|
||||||
@@ -114,7 +132,7 @@ impl<F: PrimeField> MerkleTree<F> {
|
|||||||
siblings = Self::go_down(path_inv, self.root.clone(), siblings);
|
siblings = Self::go_down(path_inv, self.root.clone(), siblings);
|
||||||
return siblings;
|
return siblings;
|
||||||
}
|
}
|
||||||
fn go_down(path: Vec<bool>, node: Node<F>, mut siblings: Vec<F>) -> Vec<F> {
|
fn go_down(path: Vec<bool>, node: Node<F, H>, mut siblings: Vec<F>) -> Vec<F> {
|
||||||
if !node.value.is_none() {
|
if !node.value.is_none() {
|
||||||
return siblings;
|
return siblings;
|
||||||
}
|
}
|
||||||
@@ -126,20 +144,14 @@ impl<F: PrimeField> MerkleTree<F> {
|
|||||||
return Self::go_down(path[1..].to_vec(), *node.right.unwrap(), siblings);
|
return Self::go_down(path[1..].to_vec(), *node.right.unwrap(), siblings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn verify(params: &Params<F>, root: F, index: F, value: F, siblings: Vec<F>) -> bool {
|
pub fn verify(root: F, index: F, value: F, siblings: Vec<F>) -> bool {
|
||||||
let mut h = params.poseidon_hash.hash(&[value]).unwrap();
|
let mut h = H::hash(&[value]);
|
||||||
let path = Self::get_path(siblings.len() as u32, index);
|
let path = Self::get_path(siblings.len() as u32, index);
|
||||||
for i in 0..siblings.len() {
|
for i in 0..siblings.len() {
|
||||||
if !path[i] {
|
if !path[i] {
|
||||||
h = params
|
h = H::hash(&[h, siblings[siblings.len() - 1 - i]]);
|
||||||
.poseidon_hash
|
|
||||||
.hash(&[h, siblings[siblings.len() - 1 - i]])
|
|
||||||
.unwrap();
|
|
||||||
} else {
|
} else {
|
||||||
h = params
|
h = H::hash(&[siblings[siblings.len() - 1 - i], h]);
|
||||||
.poseidon_hash
|
|
||||||
.hash(&[siblings[siblings.len() - 1 - i], h])
|
|
||||||
.unwrap();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if h == root {
|
if h == root {
|
||||||
@@ -149,47 +161,6 @@ impl<F: PrimeField> MerkleTree<F> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct MerkleTreePoseidon<F: PrimeField>(MerkleTree<F>);
|
|
||||||
|
|
||||||
impl<F: PrimeField> MerkleTreePoseidon<F> {
|
|
||||||
pub fn commit(values: &[F]) -> (F, Self) {
|
|
||||||
let poseidon_params = poseidon_setup_params::<F>(Curve::Bn254, 5, 4);
|
|
||||||
let poseidon_hash = poseidon::Poseidon::new(poseidon_params);
|
|
||||||
let params = MerkleTree::setup(&poseidon_hash);
|
|
||||||
let mt = MerkleTree::new(¶ms, values.to_vec());
|
|
||||||
(mt.root.hash, MerkleTreePoseidon(mt))
|
|
||||||
}
|
|
||||||
pub fn open(&self, index: F) -> Vec<F> {
|
|
||||||
self.0.gen_proof(index)
|
|
||||||
}
|
|
||||||
pub fn verify(root: F, index: F, value: F, siblings: Vec<F>) -> bool {
|
|
||||||
let poseidon_params = poseidon_setup_params::<F>(Curve::Bn254, 5, 4);
|
|
||||||
let poseidon_hash = poseidon::Poseidon::new(poseidon_params);
|
|
||||||
let params = MerkleTree::setup(&poseidon_hash);
|
|
||||||
MerkleTree::verify(¶ms, root, index, value, siblings)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn poseidon_setup_params<F: PrimeField>(
|
|
||||||
curve: Curve,
|
|
||||||
exp: i8,
|
|
||||||
width: u8,
|
|
||||||
) -> poseidon::PoseidonParameters<F> {
|
|
||||||
let pos_data = setup_poseidon_params(curve, exp, width).unwrap();
|
|
||||||
|
|
||||||
let mds_f = bytes_matrix_to_f(&pos_data.mds);
|
|
||||||
let rounds_f = bytes_vec_to_f(&pos_data.rounds);
|
|
||||||
|
|
||||||
poseidon::PoseidonParameters {
|
|
||||||
mds_matrix: mds_f,
|
|
||||||
round_keys: rounds_f,
|
|
||||||
full_rounds: pos_data.full_rounds,
|
|
||||||
partial_rounds: pos_data.partial_rounds,
|
|
||||||
sbox: poseidon::sbox::PoseidonSbox(pos_data.exp),
|
|
||||||
width: pos_data.width,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
@@ -199,47 +170,41 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_path() {
|
fn test_path() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
MerkleTree::get_path(8, Fr::from(0_u32)),
|
MerkleTree::<Fr, Keccak256Hash<Fr>>::get_path(8, Fr::from(0_u32)),
|
||||||
[false, false, false, false, false, false, false, false]
|
[false, false, false, false, false, false, false, false]
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
MerkleTree::get_path(8, Fr::from(1_u32)),
|
MerkleTree::<Fr, Keccak256Hash<Fr>>::get_path(8, Fr::from(1_u32)),
|
||||||
[true, false, false, false, false, false, false, false]
|
[true, false, false, false, false, false, false, false]
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
MerkleTree::get_path(8, Fr::from(2_u32)),
|
MerkleTree::<Fr, Keccak256Hash<Fr>>::get_path(8, Fr::from(2_u32)),
|
||||||
[false, true, false, false, false, false, false, false]
|
[false, true, false, false, false, false, false, false]
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
MerkleTree::get_path(8, Fr::from(3_u32)),
|
MerkleTree::<Fr, Keccak256Hash<Fr>>::get_path(8, Fr::from(3_u32)),
|
||||||
[true, true, false, false, false, false, false, false]
|
[true, true, false, false, false, false, false, false]
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
MerkleTree::get_path(8, Fr::from(254_u32)),
|
MerkleTree::<Fr, Keccak256Hash<Fr>>::get_path(8, Fr::from(254_u32)),
|
||||||
[false, true, true, true, true, true, true, true]
|
[false, true, true, true, true, true, true, true]
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
MerkleTree::get_path(8, Fr::from(255_u32)),
|
MerkleTree::<Fr, Keccak256Hash<Fr>>::get_path(8, Fr::from(255_u32)),
|
||||||
[true, true, true, true, true, true, true, true]
|
[true, true, true, true, true, true, true, true]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_new_empty_tree() {
|
fn test_new_empty_tree() {
|
||||||
let poseidon_params = poseidon_setup_params::<Fr>(Curve::Bn254, 5, 4);
|
let (root, mt) = MerkleTree::<Fr, Keccak256Hash<Fr>>::commit(&[]);
|
||||||
let poseidon_hash = poseidon::Poseidon::new(poseidon_params);
|
|
||||||
|
|
||||||
let params = MerkleTree::setup(&poseidon_hash);
|
|
||||||
let mt = MerkleTree::new(¶ms, Vec::new());
|
|
||||||
assert_eq!(mt.root.hash, Fr::from(0_u32));
|
assert_eq!(mt.root.hash, Fr::from(0_u32));
|
||||||
|
assert_eq!(root, Fr::from(0_u32));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_proof() {
|
fn test_proof() {
|
||||||
let poseidon_params = poseidon_setup_params::<Fr>(Curve::Bn254, 5, 4);
|
type MT = MerkleTree<Fr, Keccak256Hash<Fr>>;
|
||||||
let poseidon_hash = poseidon::Poseidon::new(poseidon_params);
|
|
||||||
|
|
||||||
let params = MerkleTree::setup(&poseidon_hash);
|
|
||||||
|
|
||||||
let values = [
|
let values = [
|
||||||
Fr::from(0_u32),
|
Fr::from(0_u32),
|
||||||
@@ -252,32 +217,22 @@ mod tests {
|
|||||||
Fr::from(203_u32),
|
Fr::from(203_u32),
|
||||||
];
|
];
|
||||||
|
|
||||||
let mt = MerkleTree::new(¶ms, values.to_vec());
|
let (root, mt) = MT::commit(&values);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
mt.root.hash.to_string(),
|
root.to_string(),
|
||||||
"Fp256 \"(10E90845D7A113686E4F2F30D73B315BA891A5DB9A58782F1260C35F99660794)\""
|
"6195952497672867974990959901930625199810318409246598214215524466855665265259"
|
||||||
);
|
);
|
||||||
|
|
||||||
let index = 3;
|
let index = 3;
|
||||||
let index_F = Fr::from(index as u32);
|
let index_F = Fr::from(index as u32);
|
||||||
let siblings = mt.gen_proof(index_F);
|
let siblings = mt.open(index_F);
|
||||||
|
|
||||||
assert!(MerkleTree::verify(
|
assert!(MT::verify(root, index_F, values[index], siblings));
|
||||||
¶ms,
|
|
||||||
mt.root.hash,
|
|
||||||
index_F,
|
|
||||||
values[index],
|
|
||||||
siblings
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_proofs() {
|
fn test_proofs() {
|
||||||
let poseidon_params = poseidon_setup_params::<Fr>(Curve::Bn254, 5, 4);
|
type MT = MerkleTree<Fr, Keccak256Hash<Fr>>;
|
||||||
let poseidon_hash = poseidon::Poseidon::new(poseidon_params);
|
|
||||||
|
|
||||||
let params = MerkleTree::setup(&poseidon_hash);
|
|
||||||
|
|
||||||
let mut rng = ark_std::test_rng();
|
let mut rng = ark_std::test_rng();
|
||||||
|
|
||||||
let n_values = 64;
|
let n_values = 64;
|
||||||
@@ -287,19 +242,13 @@ mod tests {
|
|||||||
values.push(v);
|
values.push(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mt = MerkleTree::new(¶ms, values.to_vec());
|
let (root, mt) = MT::commit(&values);
|
||||||
assert_eq!(mt.nlevels, 6);
|
assert_eq!(mt.nlevels, 6);
|
||||||
|
|
||||||
for i in 0..n_values {
|
for i in 0..n_values {
|
||||||
let i_Fr = Fr::from(i as u32);
|
let i_Fr = Fr::from(i as u32);
|
||||||
let siblings = mt.gen_proof(i_Fr);
|
let siblings = mt.open(i_Fr);
|
||||||
assert!(MerkleTree::verify(
|
assert!(MT::verify(root, i_Fr, values[i], siblings));
|
||||||
¶ms,
|
|
||||||
mt.root.hash,
|
|
||||||
i_Fr,
|
|
||||||
values[i],
|
|
||||||
siblings
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ impl<F: PrimeField> Transcript<F> {
|
|||||||
}
|
}
|
||||||
pub fn add<T: CanonicalSerialize>(&mut self, label: &'static [u8], r: &T) {
|
pub fn add<T: CanonicalSerialize>(&mut self, label: &'static [u8], r: &T) {
|
||||||
let mut buf = vec![];
|
let mut buf = vec![];
|
||||||
r.serialize(&mut buf).unwrap();
|
r.serialize_uncompressed(&mut buf).unwrap();
|
||||||
self.transcript.append_message(label, buf.as_ref());
|
self.transcript.append_message(label, buf.as_ref());
|
||||||
}
|
}
|
||||||
pub fn get_challenge(&mut self, label: &'static [u8]) -> F {
|
pub fn get_challenge(&mut self, label: &'static [u8]) -> F {
|
||||||
|
|||||||
Reference in New Issue
Block a user