Skip to content

Commit

Permalink
Merge branch 'main' into docs-fix-spelling-issues
Browse files Browse the repository at this point in the history
  • Loading branch information
igaray authored Sep 5, 2024
2 parents 04bbafe + 3795dbc commit 04690bc
Show file tree
Hide file tree
Showing 23 changed files with 386 additions and 168 deletions.
8 changes: 4 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@ exclude = ["ensure-no_std"]
resolver = "2"

[workspace.package]
version = "0.9.0"
version = "0.10.0"
edition = "2021"
license = "Apache-2.0"
repository = "https://github.com/lambdaclass/lambdaworks"

[workspace.dependencies]
iai-callgrind = "0.3.1"
lambdaworks-crypto = { path = "./crypto", version = "0.9.0", default-features = false }
lambdaworks-gpu = { path = "./gpu", version = "0.9.0" }
lambdaworks-math = { path = "./math", version = "0.9.0", default-features = false }
lambdaworks-crypto = { path = "./crypto", version = "0.10.0", default-features = false }
lambdaworks-gpu = { path = "./gpu", version = "0.10.0" }
lambdaworks-math = { path = "./math", version = "0.10.0", default-features = false }
stark-platinum-prover = { path = "./provers/stark" }
cairo-platinum-prover = { path = "./provers/cairo" }
lambdaworks-winterfell-adapter = { path = "./provers/winterfell_adapter"}
Expand Down
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,12 +136,18 @@ This can be used in a multi prover setting for extra security, or as a standalon

Fuzzers are divided between the ones that use only the CPU, the ones that use Metal, and the ones that use CUDA.

To use them, make sure you have installed ```cargo fuzzer```

You can install it with:

```cargo install cargo-fuzz```

CPU Fuzzers can be run with the command ```bash make run-fuzzer FUZZER=fuzzer_name```

For example:

```bash
make run-fuzzer FUZZER=field_from_hex
make run-fuzzer FUZZER=stark252
```

The list of fuzzers can be found in `fuzz/no_gpu_fuzz`
Expand Down Expand Up @@ -203,4 +209,4 @@ The following links, repos, companies and projects have been important in the de
- [CAIRO whitepaper](https://eprint.iacr.org/2021/1063.pdf)
- [Gnark](https://github.com/Consensys/gnark)
- [Constantine](https://github.com/mratsim/constantine)
- [Plonky3](https://github.com/Plonky3/Plonky3)
- [Plonky3](https://github.com/Plonky3/Plonky3)
12 changes: 8 additions & 4 deletions crypto/src/merkle_tree/backends/field_element.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ mod tests {
#[test]
fn hash_data_field_element_backend_works_with_keccak_256() {
let values: Vec<FE> = (1..6).map(FE::from).collect();
let merkle_tree = MerkleTree::<FieldElementBackend<F, Keccak256, 32>>::build(&values);
let merkle_tree =
MerkleTree::<FieldElementBackend<F, Keccak256, 32>>::build(&values).unwrap();
let proof = merkle_tree.get_proof_by_pos(0).unwrap();
assert!(proof.verify::<FieldElementBackend<F, Keccak256, 32>>(
&merkle_tree.root,
Expand All @@ -103,7 +104,8 @@ mod tests {
#[test]
fn hash_data_field_element_backend_works_with_sha3_256() {
let values: Vec<FE> = (1..6).map(FE::from).collect();
let merkle_tree = MerkleTree::<FieldElementBackend<F, Sha3_256, 32>>::build(&values);
let merkle_tree =
MerkleTree::<FieldElementBackend<F, Sha3_256, 32>>::build(&values).unwrap();
let proof = merkle_tree.get_proof_by_pos(0).unwrap();
assert!(proof.verify::<FieldElementBackend<F, Sha3_256, 32>>(
&merkle_tree.root,
Expand All @@ -115,7 +117,8 @@ mod tests {
#[test]
fn hash_data_field_element_backend_works_with_keccak_512() {
let values: Vec<FE> = (1..6).map(FE::from).collect();
let merkle_tree = MerkleTree::<FieldElementBackend<F, Keccak512, 64>>::build(&values);
let merkle_tree =
MerkleTree::<FieldElementBackend<F, Keccak512, 64>>::build(&values).unwrap();
let proof = merkle_tree.get_proof_by_pos(0).unwrap();
assert!(proof.verify::<FieldElementBackend<F, Keccak512, 64>>(
&merkle_tree.root,
Expand All @@ -127,7 +130,8 @@ mod tests {
#[test]
fn hash_data_field_element_backend_works_with_sha3_512() {
let values: Vec<FE> = (1..6).map(FE::from).collect();
let merkle_tree = MerkleTree::<FieldElementBackend<F, Sha3_512, 64>>::build(&values);
let merkle_tree =
MerkleTree::<FieldElementBackend<F, Sha3_512, 64>>::build(&values).unwrap();
let proof = merkle_tree.get_proof_by_pos(0).unwrap();
assert!(proof.verify::<FieldElementBackend<F, Sha3_512, 64>>(
&merkle_tree.root,
Expand Down
15 changes: 10 additions & 5 deletions crypto/src/merkle_tree/backends/field_element_vector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@ mod tests {
vec![FE::from(8u64), FE::from(19u64)],
vec![FE::from(9u64), FE::from(21u64)],
];
let merkle_tree = MerkleTree::<FieldElementVectorBackend<F, Sha3_256, 32>>::build(&values);
let merkle_tree =
MerkleTree::<FieldElementVectorBackend<F, Sha3_256, 32>>::build(&values).unwrap();
let proof = merkle_tree.get_proof_by_pos(0).unwrap();
assert!(proof.verify::<FieldElementVectorBackend<F, Sha3_256, 32>>(
&merkle_tree.root,
Expand All @@ -132,7 +133,8 @@ mod tests {
vec![FE::from(8u64), FE::from(19u64)],
vec![FE::from(9u64), FE::from(21u64)],
];
let merkle_tree = MerkleTree::<FieldElementVectorBackend<F, Keccak256, 32>>::build(&values);
let merkle_tree =
MerkleTree::<FieldElementVectorBackend<F, Keccak256, 32>>::build(&values).unwrap();
let proof = merkle_tree.get_proof_by_pos(0).unwrap();
assert!(proof.verify::<FieldElementVectorBackend<F, Keccak256, 32>>(
&merkle_tree.root,
Expand All @@ -153,7 +155,8 @@ mod tests {
vec![FE::from(8u64), FE::from(19u64)],
vec![FE::from(9u64), FE::from(21u64)],
];
let merkle_tree = MerkleTree::<FieldElementVectorBackend<F, Sha3_512, 64>>::build(&values);
let merkle_tree =
MerkleTree::<FieldElementVectorBackend<F, Sha3_512, 64>>::build(&values).unwrap();
let proof = merkle_tree.get_proof_by_pos(0).unwrap();
assert!(proof.verify::<FieldElementVectorBackend<F, Sha3_512, 64>>(
&merkle_tree.root,
Expand All @@ -174,7 +177,8 @@ mod tests {
vec![FE::from(8u64), FE::from(19u64)],
vec![FE::from(9u64), FE::from(21u64)],
];
let merkle_tree = MerkleTree::<FieldElementVectorBackend<F, Keccak512, 64>>::build(&values);
let merkle_tree =
MerkleTree::<FieldElementVectorBackend<F, Keccak512, 64>>::build(&values).unwrap();
let proof = merkle_tree.get_proof_by_pos(0).unwrap();
assert!(proof.verify::<FieldElementVectorBackend<F, Keccak512, 64>>(
&merkle_tree.root,
Expand All @@ -195,7 +199,8 @@ mod tests {
vec![FE::from(8u64), FE::from(19u64)],
vec![FE::from(9u64), FE::from(21u64)],
];
let merkle_tree = MerkleTree::<FieldElementVectorBackend<F, Sha512, 64>>::build(&values);
let merkle_tree =
MerkleTree::<FieldElementVectorBackend<F, Sha512, 64>>::build(&values).unwrap();
let proof = merkle_tree.get_proof_by_pos(0).unwrap();
assert!(proof.verify::<FieldElementVectorBackend<F, Sha512, 64>>(
&merkle_tree.root,
Expand Down
21 changes: 15 additions & 6 deletions crypto/src/merkle_tree/merkle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,11 @@ impl<B> MerkleTree<B>
where
B: IsMerkleTreeBackend,
{
pub fn build(unhashed_leaves: &[B::Data]) -> Self {
pub fn build(unhashed_leaves: &[B::Data]) -> Option<Self> {
if unhashed_leaves.is_empty() {
return None;
}

let hashed_leaves: Vec<B::Node> = B::hash_leaves(unhashed_leaves);

//The leaf must be a power of 2 set
Expand All @@ -45,10 +49,10 @@ where
//Build the inner nodes of the tree
build::<B>(&mut nodes, leaves_len);

MerkleTree {
Some(MerkleTree {
root: nodes[ROOT].clone(),
nodes,
}
})
}

pub fn get_proof_by_pos(&self, pos: usize) -> Option<Proof<B::Node>> {
Expand Down Expand Up @@ -95,7 +99,7 @@ mod tests {
#[test]
fn build_merkle_tree_from_a_power_of_two_list_of_values() {
let values: Vec<FE> = (1..5).map(FE::new).collect();
let merkle_tree = MerkleTree::<TestBackend<U64PF>>::build(&values);
let merkle_tree = MerkleTree::<TestBackend<U64PF>>::build(&values).unwrap();
assert_eq!(merkle_tree.root, FE::new(7)); // Adjusted expected value
}

Expand All @@ -107,7 +111,7 @@ mod tests {
type FE = FieldElement<U64PF>;

let values: Vec<FE> = (1..6).map(FE::new).collect();
let merkle_tree = MerkleTree::<TestBackend<U64PF>>::build(&values);
let merkle_tree = MerkleTree::<TestBackend<U64PF>>::build(&values).unwrap();
assert_eq!(merkle_tree.root, FE::new(8)); // Adjusted expected value
}

Expand All @@ -118,7 +122,12 @@ mod tests {
type FE = FieldElement<U64PF>;

let values: Vec<FE> = vec![FE::new(1)]; // Single element
let merkle_tree = MerkleTree::<TestBackend<U64PF>>::build(&values);
let merkle_tree = MerkleTree::<TestBackend<U64PF>>::build(&values).unwrap();
assert_eq!(merkle_tree.root, FE::new(4)); // Adjusted expected value
}

#[test]
fn build_empty_tree_should_not_panic() {
assert!(MerkleTree::<TestBackend<U64PF>>::build(&[]).is_none());
}
}
8 changes: 4 additions & 4 deletions crypto/src/merkle_tree/proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ mod tests {
fn create_a_proof_over_value_that_belongs_to_a_given_merkle_tree_when_given_the_leaf_position()
{
let values: Vec<FE> = (1..6).map(FE::new).collect();
let merkle_tree = MerkleTree::<TestBackend<U64PF>>::build(&values);
let merkle_tree = MerkleTree::<TestBackend<U64PF>>::build(&values).unwrap();
let proof = &merkle_tree.get_proof_by_pos(1).unwrap();
assert_merkle_path(&proof.merkle_path, &[FE::new(2), FE::new(1), FE::new(1)]);
assert!(proof.verify::<TestBackend<U64PF>>(&merkle_tree.root, 1, &FE::new(2)));
Expand All @@ -132,7 +132,7 @@ mod tests {
#[cfg(feature = "alloc")]
fn merkle_proof_verifies_after_serialization_and_deserialization() {
let values: Vec<Ecgfp5FE> = (1..6).map(Ecgfp5FE::new).collect();
let merkle_tree = TestMerkleTreeEcgfp::build(&values);
let merkle_tree = TestMerkleTreeEcgfp::build(&values).unwrap();
let proof = merkle_tree.get_proof_by_pos(1).unwrap();
let serialize_proof = proof.serialize();
let proof: TestProofEcgfp5 = Proof::deserialize(&serialize_proof).unwrap();
Expand All @@ -142,7 +142,7 @@ mod tests {
#[test]
fn create_a_merkle_tree_with_10000_elements_and_verify_that_an_element_is_part_of_it() {
let values: Vec<Ecgfp5FE> = (1..10000).map(Ecgfp5FE::new).collect();
let merkle_tree = TestMerkleTreeEcgfp::build(&values);
let merkle_tree = TestMerkleTreeEcgfp::build(&values).unwrap();
let proof = merkle_tree.get_proof_by_pos(9349).unwrap();
assert!(proof.verify::<TestBackend<Ecgfp5>>(&merkle_tree.root, 9349, &Ecgfp5FE::new(9350)));
}
Expand All @@ -160,7 +160,7 @@ mod tests {
type FE = FieldElement<U64PF>;

let values: Vec<FE> = vec![FE::new(1)]; // Single element
let merkle_tree = MerkleTree::<TestBackend<U64PF>>::build(&values);
let merkle_tree = MerkleTree::<TestBackend<U64PF>>::build(&values).unwrap();

// Update the expected root value based on the actual logic of TestBackend
// For example, if combining two `1`s results in `4`, update this accordingly
Expand Down
14 changes: 9 additions & 5 deletions crypto/src/merkle_tree/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ where
{
let mut level_begin_index = leaves_len - 1;
let mut level_end_index = 2 * level_begin_index;
loop {
while level_begin_index != level_end_index {
let new_level_begin_index = level_begin_index / 2;
let new_level_length = level_begin_index - new_level_begin_index;

Expand All @@ -68,10 +68,6 @@ where

level_end_index = level_begin_index - 1;
level_begin_index = new_level_begin_index;

if level_begin_index == level_end_index {
return;
}
}
}

Expand All @@ -87,6 +83,14 @@ mod tests {
const MODULUS: u64 = 13;
type U64PF = U64PrimeField<MODULUS>;
type FE = FieldElement<U64PF>;

#[test]
fn build_merkle_tree_one_element_must_succeed() {
let mut nodes = [FE::zero()];

build::<TestBackend<U64PF>>(&mut nodes, 1);
}

#[test]
// expected |2|4|6|8|
fn hash_leaves_from_a_list_of_field_elemnts() {
Expand Down
6 changes: 4 additions & 2 deletions examples/merkle-tree-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ fn load_tree_values(tree_path: &String) -> Result<Vec<FE>, io::Error> {
fn generate_merkle_tree(tree_path: String) -> Result<(), io::Error> {
let values: Vec<FE> = load_tree_values(&tree_path)?;

let merkle_tree = MerkleTree::<TreePoseidon<PoseidonCairoStark252>>::build(&values);
let merkle_tree = MerkleTree::<TreePoseidon<PoseidonCairoStark252>>::build(&values)
.ok_or_else(|| io::Error::new(io::ErrorKind::Other, "requested empty tree"))?;
let root = merkle_tree.root.representative().to_string();
println!("Generated merkle tree with root: {:?}", root);

Expand All @@ -45,7 +46,8 @@ fn generate_merkle_tree(tree_path: String) -> Result<(), io::Error> {

fn generate_merkle_proof(tree_path: String, pos: usize) -> Result<(), io::Error> {
let values: Vec<FE> = load_tree_values(&tree_path)?;
let merkle_tree = MerkleTree::<TreePoseidon<PoseidonCairoStark252>>::build(&values);
let merkle_tree = MerkleTree::<TreePoseidon<PoseidonCairoStark252>>::build(&values)
.ok_or_else(|| io::Error::new(io::ErrorKind::Other, "requested empty tree"))?;

let Some(proof) = merkle_tree.get_proof_by_pos(pos) else {
return Err(io::Error::new(io::ErrorKind::Other, "Index out of bounds"));
Expand Down
16 changes: 11 additions & 5 deletions fuzz/no_gpu_fuzz/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,19 +36,25 @@ test = false
doc = false

[[bin]]
name = "field_fuzzer"
path = "fuzz_targets/field/fuzzer.rs"
name = "secp256k1"
path = "fuzz_targets/field/secp256k1.rs"
test = false
doc = false

[[bin]]
name = "field_fuzz_mersenne31"
name = "stark252"
path = "fuzz_targets/field/stark252.rs"
test = false
doc = false

[[bin]]
name = "mersenne31"
path = "fuzz_targets/field/mersenne31.rs"
test = false
doc = false

[[bin]]
name = "field_mini_goldilocks"
name = "mini_goldilocks"
path = "fuzz_targets/field/mini_goldilocks.rs"
test = false
doc = false
Expand All @@ -66,7 +72,7 @@ test = false
doc = false

[[bin]]
name = "stark_field_addition"
name = "stark252_addition"
path = "fuzz_targets/field/stark_field_addition.rs"
test = false
doc = false
Expand Down
Loading

0 comments on commit 04690bc

Please sign in to comment.