diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..d28d7fd --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,77 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + +env: + CARGO_TERM_COLOR: always + +jobs: + fmt: + name: Format + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - run: rustup component add rustfmt + - run: cargo fmt --check + + clippy: + name: Clippy + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - run: rustup component add clippy + - uses: actions/cache@v4 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + target + key: clippy-${{ hashFiles('Cargo.lock') }} + - run: cargo clippy --all-features --tests -- -D warnings + + build: + name: Build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/cache@v4 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + target + key: build-${{ hashFiles('Cargo.lock') }} + - run: cargo build --all-features + + no-std: + name: Build no-std (wasm32) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - run: rustup target add wasm32-unknown-unknown + - uses: actions/cache@v4 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + target + key: wasm-${{ hashFiles('Cargo.lock') }} + - run: cargo build --target wasm32-unknown-unknown --no-default-features + + test: + name: Tests + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/cache@v4 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + target + key: test-${{ hashFiles('Cargo.lock') }} + - run: cargo test --release --all-features + diff --git a/src/demo.rs b/src/demo.rs index fc65efd..4a40d15 100644 --- a/src/demo.rs +++ b/src/demo.rs @@ -56,7 +56,7 @@ impl GenerateVerifiable for Trivial { } fn member_from_secret(secret: &Self::Secret) -> Self::Member { - secret.clone() + *secret } #[cfg(feature = "prover")] @@ -69,7 +69,7 @@ impl GenerateVerifiable for Trivial { if !set.contains(member) { return Err(()); } - Ok((member.clone(), set)) + Ok((*member, set)) } #[cfg(feature = "prover")] @@ -82,7 +82,7 @@ impl GenerateVerifiable for Trivial { if &member != secret { return Err(()); } - Ok(((secret.clone()), secret.clone())) + Ok((*secret, *secret)) } fn validate( @@ -92,19 +92,19 @@ impl GenerateVerifiable for Trivial { _context: &[u8], _message: &[u8], ) -> Result { - if members.contains(&proof) { - Ok(proof.clone()) + if members.contains(proof) { + Ok(*proof) } else { Err(()) } } fn alias_in_context(secret: &Self::Secret, _context: &[u8]) -> Result { - Ok(secret.clone()) + Ok(*secret) } fn sign(secret: &Self::Secret, _message: &[u8]) -> Result { - Ok(secret.clone()) + Ok(*secret) } fn verify_signature( @@ -179,7 +179,7 @@ impl GenerateVerifiable for Simple { if !set.contains(member) { return Err(()); } - Ok((member.clone(), set)) + Ok((*member, set)) } #[cfg(feature = "prover")] @@ -189,7 +189,7 @@ impl GenerateVerifiable for Simple { context: &[u8], message: &[u8], ) -> Result<(Self::Proof, Alias), ()> { - let public = Self::member_from_secret(&secret); + let public = Self::member_from_secret(secret); if member != public { return Err(()); } @@ -199,7 +199,7 @@ impl GenerateVerifiable for Simple { let sig = (context, message) .using_encoded(|b| pair.sign(signing_context(SIG_CON).bytes(b)).to_bytes()); - Ok(((sig, public.clone()), public)) + Ok(((sig, public), public)) } fn validate( @@ -216,13 +216,13 @@ impl GenerateVerifiable for Simple { let p = PublicKey::from_bytes(&proof.1).unwrap(); (context, message).using_encoded(|b| { p.verify_simple(SIG_CON, b, &s) - .map(|_| proof.1.clone()) + .map(|_| proof.1) .map_err(|_| ()) }) } fn alias_in_context(secret: &Self::Secret, _context: &[u8]) -> Result { - Ok(Self::member_from_secret(&secret)) + Ok(Self::member_from_secret(secret)) } fn sign(secret: &Self::Secret, message: &[u8]) -> Result { @@ -259,13 +259,11 @@ mod tests { let bob = ::member_from_secret(&bob_sec); let mut inter = ::start_members(()); - ::push_members( - &mut inter, - [alice.clone()].into_iter(), - |_| Ok(alloc::vec![()]), - ) + ::push_members(&mut inter, [alice].into_iter(), |_| { + Ok(alloc::vec![()]) + }) .unwrap(); - ::push_members(&mut inter, [bob.clone()].into_iter(), |_| { + ::push_members(&mut inter, [bob].into_iter(), |_| { Ok(alloc::vec![()]) }) .unwrap(); diff --git a/src/lib.rs b/src/lib.rs index f0f4577..b2521db 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,5 @@ #![cfg_attr(not(feature = "std"), no_std)] +#![allow(clippy::result_unit_err)] extern crate alloc; extern crate core; @@ -159,7 +160,7 @@ pub trait GenerateVerifiable { /// individual. /// /// - `context`: The context under which membership is proven. Proofs over different `[u8]`s - /// are unlinkable. + /// are unlinkable. /// /// NOTE: We never expect to use this code on-chain; it should be used only in the wallet. /// diff --git a/src/ring/bandersnatch.rs b/src/ring/bandersnatch.rs index 260fa4a..61eac30 100644 --- a/src/ring/bandersnatch.rs +++ b/src/ring/bandersnatch.rs @@ -161,7 +161,7 @@ mod tests { BandersnatchVrfVerifiable::member_from_secret(&s) }) .collect(); - let member = members[0].clone(); + let member = members[0]; let commitment = BandersnatchVrfVerifiable::open( RingDomainSize::Domain11.into(), &member, @@ -175,8 +175,7 @@ mod tests { } } -/// Tests that require the `builder-params` feature. -#[cfg(all(test, feature = "builder-params"))] +#[cfg(test)] mod builder_tests { use crate::{ring::ring_verifier_builder_params, Capacity, GenerateVerifiable}; @@ -368,7 +367,7 @@ mod builder_tests { .lookup(range) .map(|v| { v.into_iter() - .map(|i| crate::ring::StaticChunk(i)) + .map(crate::ring::StaticChunk) .collect::>() }) .ok_or(()) @@ -376,20 +375,15 @@ mod builder_tests { BandersnatchVrfVerifiable::push_members( &mut inter1, - [alice.clone(), bob.clone(), charlie.clone()].into_iter(), + [alice, bob, charlie].into_iter(), get_many, ) .unwrap(); - BandersnatchVrfVerifiable::push_members(&mut inter2, [alice.clone()].into_iter(), get_many) + BandersnatchVrfVerifiable::push_members(&mut inter2, [alice].into_iter(), get_many) .unwrap(); - BandersnatchVrfVerifiable::push_members(&mut inter2, [bob.clone()].into_iter(), get_many) + BandersnatchVrfVerifiable::push_members(&mut inter2, [bob].into_iter(), get_many).unwrap(); + BandersnatchVrfVerifiable::push_members(&mut inter2, [charlie].into_iter(), get_many) .unwrap(); - BandersnatchVrfVerifiable::push_members( - &mut inter2, - [charlie.clone()].into_iter(), - get_many, - ) - .unwrap(); assert_eq!(inter1, inter2); let members1 = BandersnatchVrfVerifiable::finish_members(inter1); @@ -417,7 +411,7 @@ mod builder_tests { .lookup(range) .map(|v| { v.into_iter() - .map(|i| crate::ring::StaticChunk(i)) + .map(crate::ring::StaticChunk) .collect::>() }) .ok_or(()) @@ -431,7 +425,7 @@ mod builder_tests { // Construct the first set with all members added simultaneously. BandersnatchVrfVerifiable::push_members( &mut inter1, - [alice.clone(), bob.clone(), charlie.clone()].into_iter(), + [alice, bob, charlie].into_iter(), get_many, ) .unwrap(); @@ -439,32 +433,23 @@ mod builder_tests { // Construct the second set with all members added simultaneously. BandersnatchVrfVerifiable::push_members( &mut inter2, - [alice.clone(), bob.clone(), charlie.clone()].into_iter(), + [alice, bob, charlie].into_iter(), get_many, ) .unwrap(); // Construct the third set with all members added sequentially. - BandersnatchVrfVerifiable::push_members(&mut inter3, [alice.clone()].into_iter(), get_many) + BandersnatchVrfVerifiable::push_members(&mut inter3, [alice].into_iter(), get_many) .unwrap(); - BandersnatchVrfVerifiable::push_members(&mut inter3, [bob.clone()].into_iter(), get_many) + BandersnatchVrfVerifiable::push_members(&mut inter3, [bob].into_iter(), get_many).unwrap(); + BandersnatchVrfVerifiable::push_members(&mut inter3, [charlie].into_iter(), get_many) .unwrap(); - BandersnatchVrfVerifiable::push_members( - &mut inter3, - [charlie.clone()].into_iter(), - get_many, - ) - .unwrap(); // Construct the fourth set with the first member joining alone, followed by the other members joining together. - BandersnatchVrfVerifiable::push_members(&mut inter4, [alice.clone()].into_iter(), get_many) + BandersnatchVrfVerifiable::push_members(&mut inter4, [alice].into_iter(), get_many) + .unwrap(); + BandersnatchVrfVerifiable::push_members(&mut inter4, [bob, charlie].into_iter(), get_many) .unwrap(); - BandersnatchVrfVerifiable::push_members( - &mut inter4, - [bob.clone(), charlie.clone()].into_iter(), - get_many, - ) - .unwrap(); assert_eq!(inter1, inter2); assert_eq!(inter2, inter3); @@ -499,7 +484,7 @@ mod builder_tests { BandersnatchVrfVerifiable::member_from_secret(&secret) }) .collect(); - let member = members[3].clone(); + let member = members[3]; let start = Instant::now(); let commitment = @@ -523,7 +508,7 @@ mod builder_tests { .lookup(range) .map(|v| { v.into_iter() - .map(|i| crate::ring::StaticChunk(i)) + .map(crate::ring::StaticChunk) .collect::>() }) .ok_or(()) @@ -538,12 +523,8 @@ mod builder_tests { let start = Instant::now(); members.iter().for_each(|member| { - BandersnatchVrfVerifiable::push_members( - &mut inter, - [member.clone()].into_iter(), - get_many, - ) - .unwrap(); + BandersnatchVrfVerifiable::push_members(&mut inter, [*member].into_iter(), get_many) + .unwrap(); }); println!( @@ -589,14 +570,14 @@ mod builder_tests { .collect(); let member_keys: Vec<_> = secrets .iter() - .map(|s| BandersnatchVrfVerifiable::member_from_secret(s)) + .map(BandersnatchVrfVerifiable::member_from_secret) .collect(); // Create proofs from different members with different messages let mut proofs = Vec::new(); let mut expected_aliases = Vec::new(); for i in 0..num_proofs { - let member = member_keys[i].clone(); + let member = member_keys[i]; let message = format!("Message from member {}", i); let commitment = BandersnatchVrfVerifiable::open(capacity, &member, member_keys.clone().into_iter()) @@ -619,19 +600,19 @@ mod builder_tests { .lookup(range) .map(|v| { v.into_iter() - .map(|i| crate::ring::StaticChunk(i)) + .map(crate::ring::StaticChunk) .collect::>() }) .ok_or(()) }; let mut inter = BandersnatchVrfVerifiable::start_members(capacity); - BandersnatchVrfVerifiable::push_members(&mut inter, member_keys.iter().cloned(), get_many) + BandersnatchVrfVerifiable::push_members(&mut inter, member_keys.iter().copied(), get_many) .unwrap(); let members = BandersnatchVrfVerifiable::finish_members(inter); // Individual validation let start = Instant::now(); - for (proof, message, _alias) in &proofs { + for (proof, message, expected_alias) in &proofs { let alias_out = BandersnatchVrfVerifiable::validate( capacity, proof, @@ -640,7 +621,7 @@ mod builder_tests { message.as_bytes(), ) .unwrap(); - assert_eq!(&alias_out, _alias); + assert_eq!(&alias_out, expected_alias); } let individual_ms = (Instant::now() - start).as_millis(); println!( @@ -652,7 +633,7 @@ mod builder_tests { let batch_items: Vec<_> = proofs .iter() .map(|(proof, message, _)| BatchProofItem { - proof: proof.clone(), + proof: *proof, context: context.to_vec(), message: message.as_bytes().to_vec(), }) @@ -660,8 +641,7 @@ mod builder_tests { let start = Instant::now(); let aliases = - BandersnatchVrfVerifiable::batch_validate(capacity, &members, &batch_items) - .unwrap(); + BandersnatchVrfVerifiable::batch_validate(capacity, &members, &batch_items).unwrap(); let batch_ms = (Instant::now() - start).as_millis(); println!("* Batch validate {} proofs: {} ms", num_proofs, batch_ms); @@ -692,13 +672,13 @@ mod builder_tests { .collect(); let member_keys: Vec<_> = secrets .iter() - .map(|s| BandersnatchVrfVerifiable::member_from_secret(s)) + .map(BandersnatchVrfVerifiable::member_from_secret) .collect(); // Create 3 valid proofs let mut batch_items = Vec::new(); for i in 0..3 { - let member = member_keys[i].clone(); + let member = member_keys[i]; let message = format!("Message from member {}", i); let commitment = BandersnatchVrfVerifiable::open(capacity, &member, member_keys.clone().into_iter()) @@ -724,34 +704,29 @@ mod builder_tests { .lookup(range) .map(|v| { v.into_iter() - .map(|i| crate::ring::StaticChunk(i)) + .map(crate::ring::StaticChunk) .collect::>() }) .ok_or(()) }; let mut inter = BandersnatchVrfVerifiable::start_members(capacity); - BandersnatchVrfVerifiable::push_members(&mut inter, member_keys.iter().cloned(), get_many) + BandersnatchVrfVerifiable::push_members(&mut inter, member_keys.iter().copied(), get_many) .unwrap(); let members = BandersnatchVrfVerifiable::finish_members(inter); // Sanity: batch with all valid proofs should pass - assert!(BandersnatchVrfVerifiable::batch_validate( - capacity, - &members, - &batch_items, - ) - .is_ok()); + assert!( + BandersnatchVrfVerifiable::batch_validate(capacity, &members, &batch_items,).is_ok() + ); // Corrupt the proof of the second item by flipping a byte in the proof data let mut corrupted_items = batch_items.clone(); corrupted_items[1].proof[10] ^= 0xFF; - assert!(BandersnatchVrfVerifiable::batch_validate( - capacity, - &members, - &corrupted_items, - ) - .is_err()); + assert!( + BandersnatchVrfVerifiable::batch_validate(capacity, &members, &corrupted_items,) + .is_err() + ); // Also test with a wrong message on a valid proof let mut wrong_message_items = batch_items.clone(); @@ -771,7 +746,7 @@ mod builder_tests { let outsider_secret = BandersnatchVrfVerifiable::new_secret([0xFFu8; 32]); let outsider_key = BandersnatchVrfVerifiable::member_from_secret(&outsider_secret); let mut extended_keys = member_keys.clone(); - extended_keys.push(outsider_key.clone()); + extended_keys.push(outsider_key); let outsider_commitment = BandersnatchVrfVerifiable::open(capacity, &outsider_key, extended_keys.into_iter()) .unwrap(); @@ -789,16 +764,14 @@ mod builder_tests { message: b"outsider message".to_vec(), }); - assert!(BandersnatchVrfVerifiable::batch_validate( - capacity, - &members, - &outsider_items, - ) - .is_err()); + assert!( + BandersnatchVrfVerifiable::batch_validate(capacity, &members, &outsider_items,) + .is_err() + ); // Test with a proof created under a different context let wrong_context = b"WrongContext"; - let member = member_keys[0].clone(); + let member = member_keys[0]; let wrong_ctx_commitment = BandersnatchVrfVerifiable::open(capacity, &member, member_keys.clone().into_iter()) .unwrap(); @@ -812,16 +785,14 @@ mod builder_tests { let mut wrong_ctx_items = batch_items.clone(); wrong_ctx_items.push(BatchProofItem { proof: wrong_ctx_proof, - context: wrong_context.to_vec(), + context: context.to_vec(), message: b"some message".to_vec(), }); - assert!(BandersnatchVrfVerifiable::batch_validate( - capacity, - &members, - &wrong_ctx_items, - ) - .is_err()); + assert!( + BandersnatchVrfVerifiable::batch_validate(capacity, &members, &wrong_ctx_items,) + .is_err() + ); }); test_for_all_domains!(open_validate_single_vs_multiple_keys, |domain_size| { @@ -857,7 +828,7 @@ mod builder_tests { .lookup(range) .map(|v| { v.into_iter() - .map(|i| crate::ring::StaticChunk(i)) + .map(crate::ring::StaticChunk) .collect::>() }) .ok_or(()) @@ -866,12 +837,8 @@ mod builder_tests { let mut inter1 = BandersnatchVrfVerifiable::start_members(capacity); let start = Instant::now(); members.iter().for_each(|member| { - BandersnatchVrfVerifiable::push_members( - &mut inter1, - [member.clone()].into_iter(), - get_many, - ) - .unwrap(); + BandersnatchVrfVerifiable::push_members(&mut inter1, [*member].into_iter(), get_many) + .unwrap(); }); println!( "* Push {} members one at a time: {} ms", @@ -882,7 +849,7 @@ mod builder_tests { let mut inter2 = BandersnatchVrfVerifiable::start_members(capacity); let start = Instant::now(); - BandersnatchVrfVerifiable::push_members(&mut inter2, members.iter().cloned(), get_many) + BandersnatchVrfVerifiable::push_members(&mut inter2, members.iter().copied(), get_many) .unwrap(); println!( "* Push {} members simultaneously: {} ms", diff --git a/src/ring/mod.rs b/src/ring/mod.rs index 0205259..9882f11 100644 --- a/src/ring/mod.rs +++ b/src/ring/mod.rs @@ -533,7 +533,12 @@ impl GenerateVerifiable for RingVrfVerifiable { let mut aliases = Vec::with_capacity(proofs.len()); let mut batch_verifier = ark_vrf::ring::BatchVerifier::::new(verifier); - for BatchProofItem { proof, context, message } in proofs { + for BatchProofItem { + proof, + context, + message, + } in proofs + { let input_msg = [S::VRF_INPUT_DOMAIN, context.as_slice()].concat(); let input = ark_vrf::Input::::new(&input_msg[..]).expect("H2C can't fail here"); let signature = RingVrfSignature::::deserialize_compressed_unchecked(proof.as_ref())