Skip to content

Commit

Permalink
Remove dependency on rust-crypto
Browse files Browse the repository at this point in the history
  • Loading branch information
Denis Varlakov committed Sep 14, 2021
1 parent 1569c91 commit db33102
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 49 deletions.
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
# Changelog

## v0.8.0-rc4
* Implement Try and Increment when converting hash to scalar [#128] \
Improves performance and security of conversion 🔥
* Get rid of deprecated `rust-crypto` dependency [#137]
* Changed the crate providing merkle trees support: `merkle-sha3 v0.1``merkle-cbt v0.3`
* Merkle trees API has been slightly changed
* Merkle trees are generic over hash function (it used to work with keccak256 only)
* Merkle proofs built by previous versions of `curv` are incompatible with latest `curv`

[#128]: https://github.com/ZenGo-X/curv/pull/128
[#137]: https://github.com/ZenGo-X/curv/pull/137

## v0.8.0-rc3
* Fix point subtraction. Bug was introduced in `v0.8.0-rc1`. [#127]
* Add `Polynomial::lagrange_basis` function [#130]
Expand Down
5 changes: 2 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,20 @@ ff-zeroize = "0.6.3"
hex = { version = "0.4", features = ["serde"] }
hmac = "0.11"
thiserror = "1"
merkle-sha3 = "^0.1"
lazy_static = "1.4"
num-traits = "0.2"
num-integer = "0.1"
pairing-plus = "0.19"
rand = "0.7"
rand_legacy = { package = "rand", version = "0.6" }
rust-crypto = "^0.2"
serde = { version = "1.0", features = ["derive"] }
serde_bytes = "0.11"
serde_derive = "1.0"
sha2 = "0.9"
sha3 = "0.9"
old_sha2 = { package = "sha2", version = "0.8" }
zeroize = "1"
merkle-cbt = "0.3"

rust-gmp-kzen = { version = "0.5", features = ["serde_support"], optional = true }
num-bigint = { version = "0.4", features = ["serde"], optional = true }
Expand All @@ -62,4 +61,4 @@ blake2 = "0.9"
default = ["rust-gmp-kzen"]

[package.metadata.docs.rs]
rustdoc-args = [ "--html-in-header", "katex-header.html" ]
rustdoc-args = [ "--html-in-header", "katex-header.html", "--cfg", "docsrs" ]
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
[![Latest version](https://img.shields.io/crates/v/curv-kzen.svg)](https://crates.io/crates/curv-kzen)
[![Docs](https://docs.rs/curv-kzen/badge.svg)](https://docs.rs/curv-kzen)
[![License](https://img.shields.io/crates/l/curv-kzen)](LICENSE)
[![dependency status](https://deps.rs/repo/github/ZenGo-X/curv/status.svg)](https://deps.rs/repo/github/ZenGo-X/curv)

Curv
=====================================
Expand Down
115 changes: 69 additions & 46 deletions src/cryptographic_primitives/hashing/merkle_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,66 +5,90 @@
License MIT: https://github.com/KZen-networks/curv/blob/master/LICENSE
*/

// enabled via feature since it uses rust-crypto.

use std::marker::PhantomData;

use crypto::sha3::Sha3;
use merkle::{MerkleTree, Proof};
use digest::{Digest, Output};
use merkle_cbt::merkle_tree::{Merge, MerkleProof, MerkleTree, CBMT};
use serde::{Deserialize, Serialize};

use crate::cryptographic_primitives::hashing::DigestExt;
use crate::cryptographic_primitives::proofs::ProofError;
use crate::elliptic::curves::{Curve, Point};
/*
pub struct MT256<'a> {
tree: MerkleTree<GE>,
root: & 'a Vec<u8>,
}
*/
pub struct MT256<E: Curve> {
tree: MerkleTree<[u8; 32]>,
_ph: PhantomData<fn(E)>,

pub struct MT256<E: Curve, H: Digest> {
tree: MerkleTree<Output<H>, MergeDigest<H>>,
leaves: Vec<Point<E>>,
}

//impl <'a> MT256<'a>{
impl<E: Curve> MT256<E> {
pub fn create_tree(vec: &[Point<E>]) -> MT256<E> {
let digest = Sha3::keccak256();
let vec_bytes = (0..vec.len())
.map(|i| {
let mut array = [0u8; 32];
let bytes = vec[i].to_bytes(false);
array.copy_from_slice(&bytes[0..32]);
array
})
.collect::<Vec<[u8; 32]>>();
let tree = MerkleTree::from_vec::<[u8; 32]>(digest, vec_bytes);
impl<E: Curve, H: Digest + Clone> MT256<E, H> {
pub fn create_tree(leaves: Vec<Point<E>>) -> Self {
let hashes = leaves
.iter()
.map(|leaf| H::new().chain_point(leaf).finalize())
.collect::<Vec<_>>();

MT256 {
tree,
_ph: PhantomData,
tree: CBMT::<Output<H>, MergeDigest<H>>::build_merkle_tree(&hashes),
leaves,
}
}

pub fn gen_proof_for_ge(&self, value: &Point<E>) -> Proof<[u8; 32]> {
let mut array = [0u8; 32];
let pk_slice = value.to_bytes(false);
array.copy_from_slice(&pk_slice[0..32]);
MerkleTree::gen_proof::<[u8; 32]>(&self.tree, array).expect("not found in tree")
pub fn build_proof(&self, point: Point<E>) -> Option<Proof<E, H>> {
let index = (0u32..)
.zip(&self.leaves)
.find(|(_, leaf)| **leaf == point)
.map(|(i, _)| i)?;
let proof = self.tree.build_proof(&[index])?;
Some(Proof {
index: proof.indices()[0],
lemmas: proof.lemmas().to_vec(),
point,
})
}

pub fn get_root(&self) -> &Vec<u8> {
MerkleTree::root_hash(&self.tree)
pub fn get_root(&self) -> Output<H> {
self.tree.root()
}
}

#[allow(clippy::result_unit_err)]
pub fn validate_proof(proof: &Proof<[u8; 32]>, root: &[u8]) -> Result<(), ()> {
if Proof::validate::<[u8; 32]>(proof, root) {
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(bound(
serialize = "Output<H>: Serialize",
deserialize = "Output<H>: Deserialize<'de>"
))]
pub struct Proof<E: Curve, H: Digest> {
pub index: u32,
pub lemmas: Vec<Output<H>>,
pub point: Point<E>,
}

impl<E: Curve, H: Digest + Clone> Proof<E, H> {
pub fn verify(&self, root: &Output<H>) -> Result<(), ProofError> {
let leaf = H::new().chain_point(&self.point).finalize();
let valid =
MerkleProof::<Output<H>, MergeDigest<H>>::new(vec![self.index], self.lemmas.clone())
.verify(root, &[leaf]);
if valid {
Ok(())
} else {
Err(())
Err(ProofError)
}
}
}

struct MergeDigest<D>(PhantomData<D>);

impl<D> Merge for MergeDigest<D>
where
D: Digest,
{
type Item = Output<D>;

fn merge(left: &Self::Item, right: &Self::Item) -> Self::Item {
D::new().chain(left).chain(right).finalize()
}
}

#[cfg(test)]
mod tests {
use super::MT256;
Expand All @@ -80,11 +104,10 @@ mod tests {
let ge3: Point<E> = &ge1 + &ge2;
let ge4: Point<E> = &ge1 + &ge3;
let ge_vec = vec![ge1.clone(), ge2, ge3, ge4];
let mt256 = MT256::create_tree(&ge_vec);
let proof1 = mt256.gen_proof_for_ge(&ge1);
let mt256 = MT256::<_, sha3::Keccak256>::create_tree(ge_vec);
let proof1 = mt256.build_proof(ge1).unwrap();
let root = mt256.get_root();
let valid_proof = MT256::<E>::validate_proof(&proof1, root).is_ok();
assert!(valid_proof);
proof1.verify(&root).expect("proof is invalid");
}

test_for_all_curves!(test_mt_functionality_three_leaves);
Expand All @@ -95,9 +118,9 @@ mod tests {
let ge3: Point<E> = &ge1 + &ge2;

let ge_vec = vec![ge1.clone(), ge2, ge3];
let mt256 = MT256::create_tree(&ge_vec);
let proof1 = mt256.gen_proof_for_ge(&ge1);
let mt256 = MT256::<_, sha3::Keccak256>::create_tree(ge_vec);
let proof1 = mt256.build_proof(ge1).unwrap();
let root = mt256.get_root();
assert!(MT256::<E>::validate_proof(&proof1, root).is_ok());
proof1.verify(&root).expect("proof is invalid");
}
}

0 comments on commit db33102

Please sign in to comment.