From 786ef7f89094866857f2d7621bc6ff8f06b50baf Mon Sep 17 00:00:00 2001 From: Weikeng Chen Date: Fri, 4 Jun 2021 21:50:59 -0700 Subject: [PATCH] Add CHANGELOG and several housekeeping files (#53) --- .github/.markdownlint.yml | 14 +++++++ .github/PULL_REQUEST_TEMPLATE.md | 26 +++++++++++++ .github/workflows/linkify_changelog.yml | 20 ++++++++++ .github/workflows/mdlinter.yml | 34 +++++++++++++++++ CHANGELOG.md | 33 +++++++++++++++++ README.md | 7 +++- cp-benches/Cargo.toml | 6 ++- cp-benches/benches/crypto_primitives/comm.rs | 7 ++-- cp-benches/benches/crypto_primitives/crh.rs | 13 ++++--- cp-benches/benches/crypto_primitives/prf.rs | 6 +-- .../benches/crypto_primitives/signature.rs | 12 +++--- scripts/linkify_changelog.py | 30 +++++++++++++++ src/crh/mod.rs | 2 + src/crh/poseidon/mod.rs | 37 ++++--------------- src/crh/poseidon/sbox/mod.rs | 36 +++++++++--------- src/encryption/elgamal/mod.rs | 8 ++-- src/lib.rs | 1 - src/merkle_tree/mod.rs | 5 ++- src/prf/mod.rs | 2 + 19 files changed, 222 insertions(+), 77 deletions(-) create mode 100644 .github/.markdownlint.yml create mode 100644 .github/PULL_REQUEST_TEMPLATE.md create mode 100644 .github/workflows/linkify_changelog.yml create mode 100644 .github/workflows/mdlinter.yml create mode 100644 CHANGELOG.md create mode 100644 scripts/linkify_changelog.py diff --git a/.github/.markdownlint.yml b/.github/.markdownlint.yml new file mode 100644 index 00000000..936fc62e --- /dev/null +++ b/.github/.markdownlint.yml @@ -0,0 +1,14 @@ +# See https://github.com/DavidAnson/markdownlint#rules--aliases for list of markdown lint codes +default: true +# MD01 lint blocks having header's incrementing by more than # at a time. +MD001: false +MD007: { indent: 4 } +# MD013 blocks long lines +MD013: false +MD024: { siblings_only: true } +MD025: false +# MD033 lint blocks HTML in MD +MD033: false +# MD036 no-emphasis-as-heading +MD036: false +MD041: false diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 00000000..dcb2f6b0 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,26 @@ + + +## Description + + + +closes: #XXXX + +--- + +Before we can merge this PR, please make sure that all the following items have been +checked off. If any of the checklist items are not applicable, please leave them but +write a little note why. + +- [ ] Targeted PR against correct branch (main) +- [ ] Linked to Github issue with discussion and accepted design OR have an explanation in the PR that describes this work. +- [ ] Wrote unit tests +- [ ] Updated relevant documentation in the code +- [ ] Added a relevant changelog entry to the `Pending` section in `CHANGELOG.md` +- [ ] Re-reviewed `Files changed` in the Github PR explorer diff --git a/.github/workflows/linkify_changelog.yml b/.github/workflows/linkify_changelog.yml new file mode 100644 index 00000000..2c64bf2e --- /dev/null +++ b/.github/workflows/linkify_changelog.yml @@ -0,0 +1,20 @@ +name: Linkify Changelog + +on: + workflow_dispatch + +jobs: + linkify: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Add links + run: python3 scripts/linkify_changelog.py CHANGELOG.md + - name: Commit + run: | + git config user.name github-actions + git config user.email github-actions@github.com + git add . + git commit -m "Linkify Changelog" + git push \ No newline at end of file diff --git a/.github/workflows/mdlinter.yml b/.github/workflows/mdlinter.yml new file mode 100644 index 00000000..50cb2214 --- /dev/null +++ b/.github/workflows/mdlinter.yml @@ -0,0 +1,34 @@ +name: Lint +on: + push: + branches: + - master + paths: + - "**.md" + pull_request: + paths: + - "**.md" + +jobs: + build: + name: Markdown linter + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Lint Code Base + uses: docker://github/super-linter:latest + env: + LINTER_RULES_PATH: .github + VALIDATE_ALL_CODEBASE: true + DEFAULT_BRANCH: master + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + VALIDATE_MD: true + MARKDOWN_CONFIG_FILE: .markdownlint.yml + VALIDATE_PROTOBUF: false + VALIDATE_JSCPD: false + # use Python Pylint as the only linter to avoid conflicts + VALIDATE_PYTHON_BLACK: false + VALIDATE_PYTHON_FLAKE8: false + VALIDATE_PYTHON_ISORT: false + VALIDATE_PYTHON_MYPY: false \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..3f401e48 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,33 @@ +## Pending + +### Breaking changes + +- [\#30](https://github.com/arkworks-rs/crypto-primitives/pull/30) Refactor the Merkle tree to separate the leaf hash and two-to-one hash. + +### Features + +- [\#38](https://github.com/arkworks-rs/crypto-primitives/pull/38) Add a signature verification trait `SigVerifyGadget`. +- [\#44](https://github.com/arkworks-rs/crypto-primitives/pull/44) Add basic ElGamal encryption gadgets. +- [\#48](https://github.com/arkworks-rs/crypto-primitives/pull/48) Add `CanonicalSerialize` and `CanonicalDeserialize` to `Path` and `CRH` outputs. + +### Improvements + +### Bug fixes + +## v0.2.0 + +### Breaking changes + +### Features + +- [\#2](https://github.com/arkworks-rs/crypto-primitives/pull/2) Add the `SNARK` gadget traits. +- [\#3](https://github.com/arkworks-rs/crypto-primitives/pull/3) Add unchecked allocation for `ProofVar` and `VerifyingKeyVar`. +- [\#4](https://github.com/arkworks-rs/crypto-primitives/pull/4) Add `verifier_size` to `SNARKGadget`. +- [\#6](https://github.com/arkworks-rs/crypto-primitives/pull/6) Add `IntoIterator` for SNARK input gadgets. +- [\#28](https://github.com/arkworks-rs/crypto-primitives/pull/28) Adds Poseidon CRH w/ constraints. + +### Improvements + +### Bug fixes + +## v0.1.0 (Initial release of arkworks/crypto-primitives) diff --git a/README.md b/README.md index 99bbfdfa..9231a000 100644 --- a/README.md +++ b/README.md @@ -16,17 +16,20 @@ This library is released under the MIT License and the Apache v2 License (see [L ## Build guide The library compiles on the `stable` toolchain of the Rust compiler. To install the latest version of Rust, first install `rustup` by following the instructions [here](https://rustup.rs/), or via your platform's package manager. Once `rustup` is installed, install the Rust toolchain by invoking: + ```bash rustup install stable ``` After that, use `cargo`, the standard Rust build tool, to build the library: + ```bash git clone https://github.com/arkworks-rs/crypto-primitives.git cargo build --release ``` This library comes with unit tests for each of the provided crates. Run the tests with: + ```bash cargo test ``` @@ -35,8 +38,8 @@ cargo test This library is licensed under either of the following licenses, at your discretion. - * Apache License Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) - * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) +* Apache License Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or [apache.org license link](http://www.apache.org/licenses/LICENSE-2.0)) +* MIT license ([LICENSE-MIT](LICENSE-MIT) or [opensource.org license link](http://opensource.org/licenses/MIT)) Unless you explicitly state otherwise, any contribution submitted for inclusion in this library by you shall be dual licensed as above (as defined in the Apache v2 License), without any additional terms or conditions. diff --git a/cp-benches/Cargo.toml b/cp-benches/Cargo.toml index 4831cd9e..87e20e86 100644 --- a/cp-benches/Cargo.toml +++ b/cp-benches/Cargo.toml @@ -13,10 +13,12 @@ edition = "2018" ################################# Dependencies ################################ [dev-dependencies] -ark-ed-on-bls12-377 = { git = "https://github.com/arkworks-rs/curves/", default-features = false } +ark-crypto-primitives = { path = "../" } +ark-ed-on-bls12-377 = { version = "^0.2.0", default-features = false } +ark-std = { version = "^0.2.0", default-features = false } + blake2 = { version = "0.9", default-features = false } criterion = "0.3.1" -crypto-primitives = { path = "../crypto-primitives" } ################################# Benchmarks ################################## diff --git a/cp-benches/benches/crypto_primitives/comm.rs b/cp-benches/benches/crypto_primitives/comm.rs index 3f6ebeb6..25a78a2a 100644 --- a/cp-benches/benches/crypto_primitives/comm.rs +++ b/cp-benches/benches/crypto_primitives/comm.rs @@ -1,9 +1,10 @@ #[macro_use] extern crate criterion; -use algebra::{ed_on_bls12_377::EdwardsProjective as Edwards, UniformRand}; +use ark_crypto_primitives::commitment::{pedersen::*, CommitmentScheme}; +use ark_ed_on_bls12_377::EdwardsProjective as Edwards; +use ark_std::UniformRand; use criterion::Criterion; -use crypto_primitives::commitment::{pedersen::*, CommitmentScheme}; #[derive(Clone, PartialEq, Eq, Hash)] pub struct CommWindow; @@ -28,7 +29,7 @@ fn pedersen_comm_eval(c: &mut Criterion) { let input = vec![5u8; 128]; c.bench_function("Pedersen Commitment Eval", move |b| { b.iter(|| { - let rng = &mut rand::thread_rng(); + let rng = &mut ark_std::test_rng(); let commitment_randomness = Randomness::rand(rng); Commitment::::commit(¶meters, &input, &commitment_randomness) .unwrap() diff --git a/cp-benches/benches/crypto_primitives/crh.rs b/cp-benches/benches/crypto_primitives/crh.rs index d48bc98d..2196ef86 100644 --- a/cp-benches/benches/crypto_primitives/crh.rs +++ b/cp-benches/benches/crypto_primitives/crh.rs @@ -1,9 +1,12 @@ #[macro_use] extern crate criterion; -use algebra::ed_on_bls12_377::EdwardsProjective as Edwards; +use ark_crypto_primitives::crh::{ + pedersen::{Window, CRH as PedersenCRH}, + CRH, +}; +use ark_ed_on_bls12_377::EdwardsProjective as Edwards; use criterion::Criterion; -use crypto_primitives::crh::{pedersen::*, FixedLengthCRH}; #[derive(Clone, PartialEq, Eq, Hash)] pub struct HashWindow; @@ -17,17 +20,17 @@ fn pedersen_crh_setup(c: &mut Criterion) { c.bench_function("Pedersen CRH Setup", move |b| { b.iter(|| { let mut rng = &mut ark_std::test_rng(); - CRH::::setup(&mut rng).unwrap() + PedersenCRH::::setup(&mut rng).unwrap() }) }); } fn pedersen_crh_eval(c: &mut Criterion) { let mut rng = &mut ark_std::test_rng(); - let parameters = CRH::::setup(&mut rng).unwrap(); + let parameters = PedersenCRH::::setup(&mut rng).unwrap(); let input = vec![5u8; 128]; c.bench_function("Pedersen CRH Eval", move |b| { - b.iter(|| CRH::::evaluate(¶meters, &input).unwrap()) + b.iter(|| PedersenCRH::::evaluate(¶meters, &input).unwrap()) }); } diff --git a/cp-benches/benches/crypto_primitives/prf.rs b/cp-benches/benches/crypto_primitives/prf.rs index 2b9b6915..4c2eb274 100644 --- a/cp-benches/benches/crypto_primitives/prf.rs +++ b/cp-benches/benches/crypto_primitives/prf.rs @@ -1,11 +1,9 @@ -use rand; - #[macro_use] extern crate criterion; -use criterion::Criterion; -use crypto_primitives::prf::*; +use ark_crypto_primitives::prf::*; use ark_std::rand::Rng; +use criterion::Criterion; fn blake2s_prf_eval(c: &mut Criterion) { let rng = &mut ark_std::test_rng(); diff --git a/cp-benches/benches/crypto_primitives/signature.rs b/cp-benches/benches/crypto_primitives/signature.rs index 7d98a8bd..7af2cab7 100644 --- a/cp-benches/benches/crypto_primitives/signature.rs +++ b/cp-benches/benches/crypto_primitives/signature.rs @@ -1,17 +1,17 @@ #[macro_use] extern crate criterion; -use algebra::ed_on_bls12_377::EdwardsProjective as Edwards; +use ark_crypto_primitives::signature::{schnorr::*, SignatureScheme}; +use ark_ed_on_bls12_377::EdwardsProjective as Edwards; +use ark_std::rand::Rng; use blake2::Blake2s; use criterion::Criterion; -use crypto_primitives::signature::{schnorr::*, SignatureScheme}; -use ark_std::rand::Rng; type SchnorrEdwards = Schnorr; fn schnorr_signature_setup(c: &mut Criterion) { c.bench_function("SchnorrEdwards: Setup", move |b| { b.iter(|| { - let mut rng = &mut rand::thread_rng(); + let mut rng = &mut ark_std::test_rng(); SchnorrEdwards::setup(&mut rng).unwrap() }) }); @@ -23,7 +23,7 @@ fn schnorr_signature_keygen(c: &mut Criterion) { c.bench_function("SchnorrEdwards: KeyGen", move |b| { b.iter(|| { - let mut rng = &mut rand::thread_rng(); + let mut rng = &mut ark_std::test_rng(); SchnorrEdwards::keygen(¶meters, &mut rng).unwrap() }) }); @@ -37,7 +37,7 @@ fn schnorr_signature_sign(c: &mut Criterion) { c.bench_function("SchnorrEdwards: Sign", move |b| { b.iter(|| { - let mut rng = &mut rand::thread_rng(); + let mut rng = &mut ark_std::test_rng(); SchnorrEdwards::sign(¶meters, &sk, &message, &mut rng).unwrap() }) }); diff --git a/scripts/linkify_changelog.py b/scripts/linkify_changelog.py new file mode 100644 index 00000000..1d85f290 --- /dev/null +++ b/scripts/linkify_changelog.py @@ -0,0 +1,30 @@ +import fileinput +import os +import re +import sys + +# Set this to the name of the repo, if you don't want it to be read from the filesystem. +# It assumes the changelog file is in the root of the repo. +repo_name = "" + +# This script goes through the provided file, and replaces any " \#", +# with the valid mark down formatted link to it. e.g. +# " [\#number](https://github.com/arkworks-rs/template/pull/) +# Note that if the number is for a an issue, github will auto-redirect you when you click the link. +# It is safe to run the script multiple times in succession. +# +# Example usage $ python3 linkify_changelog.py ../CHANGELOG.md +changelog_path = sys.argv[1] +if repo_name == "": + path = os.path.abspath(changelog_path) + components = path.split(os.path.sep) + repo_name = components[-2] + +for line in fileinput.input(inplace=True): + line = re.sub( + r"\- #([0-9]*)", + r"- [\#\1](https://github.com/arkworks-rs/" + repo_name + r"/pull/\1)", + line.rstrip(), + ) + # edits the current file + print(line) \ No newline at end of file diff --git a/src/crh/mod.rs b/src/crh/mod.rs index b25736fc..41196d1d 100644 --- a/src/crh/mod.rs +++ b/src/crh/mod.rs @@ -1,3 +1,5 @@ +#![allow(clippy::upper_case_acronyms)] + use ark_ff::bytes::ToBytes; use ark_std::hash::Hash; use ark_std::rand::Rng; diff --git a/src/crh/poseidon/mod.rs b/src/crh/poseidon/mod.rs index f8812076..d118700c 100644 --- a/src/crh/poseidon/mod.rs +++ b/src/crh/poseidon/mod.rs @@ -49,7 +49,7 @@ impl> Poseidon { let full_rounds_end = P::FULL_ROUNDS_END; let mut current_state = input.to_vec(); - let mut current_state_temp = vec![F::zero().clone(); width]; + let mut current_state_temp = vec![F::zero(); width]; let mut round_keys_offset = 0; @@ -170,44 +170,21 @@ pub struct CRH> { params: PhantomData

, } -impl> CRH { - pub fn create_mds(_rng: &mut R) -> Vec> { - let mds_matrix = Vec::new(); - mds_matrix - } - - pub fn create_round_consts(_rng: &mut R) -> Vec { - let round_consts = Vec::new(); - round_consts - } -} - impl> CRHTrait for CRH { const INPUT_SIZE_BITS: usize = 32; type Output = F; type Parameters = Poseidon; - fn setup(rng: &mut R) -> Result { - // let time = start_timer!(|| format!( - // "Poseidon::Setup: {} {}-bit windows; {{0,1}}^{{{}}} -> C", - // W::NUM_WINDOWS, - // W::WINDOW_SIZE, - // W::NUM_WINDOWS * W::WINDOW_SIZE - // )); - - let mds = Self::create_mds(rng); - let rc = Self::create_round_consts(rng); - Ok(Self::Parameters { - params: P::default(), - round_keys: rc, - mds_matrix: mds, - }) + fn setup(_rng: &mut R) -> Result { + // automatic generation of parameters are not implemented yet + // therefore, the developers must specify the parameters themselves + unimplemented!() } // https://github.com/arkworks-rs/algebra/blob/master/ff/src/to_field_vec.rs fn evaluate(parameters: &Self::Parameters, input: &[u8]) -> Result { let eval_time = start_timer!(|| "PoseidonCRH::Eval"); - let elts: Vec = input.to_field_elements().unwrap_or(Vec::new()); + let elts: Vec = input.to_field_elements().unwrap_or_default(); let result = match elts.len() { 2 => parameters.hash_2(elts[0], elts[1]), 4 => parameters.hash_4([elts[0], elts[1], elts[2], elts[3]]), @@ -241,7 +218,7 @@ impl> TwoToOneCRH for CRH { let chained: Vec<_> = left_input .iter() .chain(right_input.iter()) - .map(|x| *x) + .copied() .collect(); ::evaluate(parameters, &chained) diff --git a/src/crh/poseidon/sbox/mod.rs b/src/crh/poseidon/sbox/mod.rs index ab34336c..aa0efe8d 100644 --- a/src/crh/poseidon/sbox/mod.rs +++ b/src/crh/poseidon/sbox/mod.rs @@ -15,35 +15,35 @@ impl PoseidonSbox { match self { PoseidonSbox::Exponentiation(val) => { match val { - 2 => elem.clone() * elem.clone(), - 3 => elem.clone() * elem.clone() * elem.clone(), + 2 => elem * &elem, + 3 => elem * &elem * &elem, 4 => { - let sqr = elem.clone() * elem.clone(); - sqr.clone() * sqr.clone() + let sqr = elem.square(); + sqr * &sqr.clone() } 5 => { - let sqr = elem.clone() * elem.clone(); - sqr.clone() * sqr.clone() * elem.clone() + let sqr = elem.square(); + sqr * &sqr.clone() * &elem } 6 => { - let sqr = elem.clone() * elem.clone(); - let quad = sqr * sqr; - sqr.clone() * quad + let sqr = elem.square(); + let quad = sqr * &sqr; + sqr * &quad } 7 => { - let sqr = elem.clone() * elem.clone(); - let quad = sqr * sqr; - sqr.clone() * quad * elem.clone() + let sqr = elem.square(); + let quad = sqr * &sqr; + sqr * &quad * &elem } 17 => { - let sqr = elem.clone() * elem.clone(); - let quad = sqr * sqr; - let eighth = quad * quad; - let sixteenth = eighth * eighth; - sixteenth * elem.clone() + let sqr = elem.square(); + let quad = sqr * &sqr; + let eighth = quad * &quad; + let sixteenth = eighth * &eighth; + sixteenth * &elem } // default to cubed - _ => elem.clone() * elem.clone() * elem.clone(), + _ => elem * &elem * &elem, } } PoseidonSbox::Inverse => elem.inverse().unwrap_or(F::zero()), diff --git a/src/encryption/elgamal/mod.rs b/src/encryption/elgamal/mod.rs index dda7c920..6e471c78 100644 --- a/src/encryption/elgamal/mod.rs +++ b/src/encryption/elgamal/mod.rs @@ -62,7 +62,7 @@ where let secret_key: ::ScalarField = C::ScalarField::rand(rng); // compute secret_key*generator to derive the public key - let public_key = pp.generator.mul(secret_key.clone()).into(); + let public_key = pp.generator.mul(secret_key).into(); Ok((public_key, SecretKey(secret_key))) } @@ -74,10 +74,10 @@ where r: &Self::Randomness, ) -> Result { // compute s = r*pk - let s = pk.mul(r.0.clone()).into(); + let s = pk.mul(r.0).into(); // compute c1 = r*generator - let c1 = pp.generator.mul(r.0.clone()).into(); + let c1 = pp.generator.mul(r.0).into(); // compute c2 = m + s let c2 = *message + s; @@ -94,7 +94,7 @@ where let c2: ::Affine = ciphertext.1; // compute s = secret_key * c1 - let s = c1.mul(sk.0.clone()); + let s = c1.mul(sk.0); let s_inv = -s; // compute message = c2 - s diff --git a/src/lib.rs b/src/lib.rs index c52137c2..3fcf7047 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,5 @@ #![cfg_attr(not(feature = "std"), no_std)] #![deny( - warnings, unused, future_incompatible, nonstandard_style, diff --git a/src/merkle_tree/mod.rs b/src/merkle_tree/mod.rs index cb89392a..bcb83c00 100644 --- a/src/merkle_tree/mod.rs +++ b/src/merkle_tree/mod.rs @@ -1,4 +1,5 @@ #![allow(unused)] // temporary +#![allow(clippy::needless_range_loop)] use crate::crh::TwoToOneCRH; use crate::CRH; @@ -45,7 +46,7 @@ impl Path

{ /// `position[i]` is 0 (false) iff `i`th on-path node from top to bottom is on the left. /// /// This function simply converts `self.leaf_index` to boolean array in big endian form. - fn position_list<'a>(&'a self) -> impl 'a + Iterator { + fn position_list(&'_ self) -> impl '_ + Iterator { (0..self.auth_path.len() + 1) .map(move |i| ((self.leaf_index >> i) & 1) != 0) .rev() @@ -340,7 +341,7 @@ impl MerkleTree

{ debug_assert_eq!(path_bottom_to_top.len(), self.height - 1); let path_top_to_bottom: Vec<_> = path_bottom_to_top.into_iter().rev().collect(); - return Ok((new_leaf_hash, path_top_to_bottom)); + Ok((new_leaf_hash, path_top_to_bottom)) } /// Update the leaf at `index` to updated leaf. diff --git a/src/prf/mod.rs b/src/prf/mod.rs index e065b755..261bae15 100644 --- a/src/prf/mod.rs +++ b/src/prf/mod.rs @@ -1,3 +1,5 @@ +#![allow(clippy::upper_case_acronyms)] + use ark_ff::bytes::{FromBytes, ToBytes}; use core::{fmt::Debug, hash::Hash};