From 5d128a6c1236f42ee7f2b5c6fa4e3d17cace9e91 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Tue, 1 Jun 2021 23:09:07 +0100 Subject: [PATCH 1/7] Add rust-toolchain file with MSRV --- rust-toolchain | 1 + 1 file changed, 1 insertion(+) create mode 100644 rust-toolchain diff --git a/rust-toolchain b/rust-toolchain new file mode 100644 index 0000000..7f3a46a --- /dev/null +++ b/rust-toolchain @@ -0,0 +1 @@ +1.49.0 From 7663200468316537cb323eac9c1a2e3721f9967c Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Tue, 1 Jun 2021 23:19:14 +0100 Subject: [PATCH 2/7] Fill in readme details --- README.md | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index cbace05..ddbb954 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,35 @@ # `pasta_curves` -**IMPORTANT**: This library is being actively developed and should not be used in production software. +This crate provides an implementation of the Pasta elliptic curve constructions, +Pallas and Vesta. More details about the Pasta curves can be found +[in this blog post](https://electriccoin.co/blog/the-pasta-curves-for-halo-2-and-beyond/). ## [Documentation](https://docs.rs/pasta_curves) -This crate currently has a Minimum Supported Rust Version of 1.49.0. When const generics -are stabilized [in Rust 1.51.0](https://github.com/rust-lang/rust/pull/79135), we plan -to require that version. +## Minimum Supported Rust Version + +Requires Rust **1.49** or higher. + +Minimum supported Rust version can be changed in the future, but it will be done with a +minor version bump. + +## Curve Descriptions + +- Pallas: y2 = x3 + 5 over + `GF(0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001)`. + +- Vesta: y2 = x3 + 5 over + `GF(0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001)`. + +The Pasta curves form a cycle with one another: the order of each curve is exactly the +base field of the other. This property is critical to the efficiency of recursive proof +systems. They are designed to be highly 2-adic, meaning that a large power-of-two +multiplicative subgroup exists in each field. This is important for the performance of +polynomial arithmetic over their scalar fields and is essential for protocols similar +to PLONK. + +These curves can be reproducibly obtained +[using a curve search utility we’ve published](https://github.com/zcash/pasta). ## License From 45c57f935201fcb40b65fc6b7501f7e13773d317 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Tue, 1 Jun 2021 23:22:25 +0100 Subject: [PATCH 3/7] Bump MSRV to 1.51.0 Necessary for ff 0.10 etc. --- .github/workflows/ci.yml | 18 +++++++++--------- README.md | 2 +- rust-toolchain | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 859e8bb..2566161 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,7 +16,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: - toolchain: stable + toolchain: 1.51.0 override: true - name: Run tests uses: actions-rs/cargo@v1 @@ -37,7 +37,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: - toolchain: stable + toolchain: 1.51.0 override: true - name: Add target run: rustup target add ${{ matrix.target }} @@ -55,7 +55,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: - toolchain: stable + toolchain: 1.51.0 override: true # Build benchmarks to prevent bitrot - name: Build benchmarks @@ -71,7 +71,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: - toolchain: stable + toolchain: 1.51.0 override: true - name: cargo build uses: actions-rs/cargo@v1 @@ -85,7 +85,7 @@ jobs: run: mdbook test -L target/debug/deps book/ clippy: - name: Clippy (stable) + name: Clippy (1.51.0) timeout-minutes: 30 runs-on: ubuntu-latest @@ -93,13 +93,13 @@ jobs: - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: - toolchain: stable + toolchain: 1.51.0 components: clippy override: true - name: Run clippy uses: actions-rs/clippy-check@v1 with: - name: Clippy (stable) + name: Clippy (1.51.0) token: ${{ secrets.GITHUB_TOKEN }} args: --all-features --all-targets -- -D warnings @@ -158,7 +158,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: - toolchain: stable + toolchain: 1.51.0 override: true - name: cargo fetch uses: actions-rs/cargo@v1 @@ -181,7 +181,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: - toolchain: stable + toolchain: 1.51.0 override: true - run: rustup component add rustfmt - uses: actions-rs/cargo@v1 diff --git a/README.md b/README.md index ddbb954..20813c8 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ Pallas and Vesta. More details about the Pasta curves can be found ## Minimum Supported Rust Version -Requires Rust **1.49** or higher. +Requires Rust **1.51** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. diff --git a/rust-toolchain b/rust-toolchain index 7f3a46a..ba0a719 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1 +1 @@ -1.49.0 +1.51.0 From bc20c5826b3755bbcaf8555b748aa4da32d024b6 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Tue, 1 Jun 2021 23:31:00 +0100 Subject: [PATCH 4/7] Migrate to ff 0.10.0 --- Cargo.toml | 9 +++++---- src/fields/fp.rs | 46 ++++++++++++++++++++++++++-------------------- src/fields/fq.rs | 46 ++++++++++++++++++++++++++-------------------- 3 files changed, 57 insertions(+), 44 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index bdb9213..c0571f5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,12 +39,13 @@ harness = false [dependencies] subtle = "2.3" -ff = "0.9" -group = "0.9" +ff = "0.10" +group = "0.10" rand = "0.8" blake2b_simd = "0.5" lazy_static = "1.4.0" static_assertions = "1.1.0" -# Temporary workaround for https://github.com/myrrlyn/funty/issues/3 -funty = "=1.1.0" +[features] +default = ["bits"] +bits = ["ff/bits"] diff --git a/src/fields/fp.rs b/src/fields/fp.rs index 406d76c..d72b0ee 100644 --- a/src/fields/fp.rs +++ b/src/fields/fp.rs @@ -1,11 +1,13 @@ use core::convert::TryInto; use core::fmt; use core::ops::{Add, Mul, Neg, Sub}; -use ff::FieldBits; use lazy_static::lazy_static; use rand::RngCore; use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; +#[cfg(feature = "bits")] +use ff::{FieldBits, PrimeFieldBits}; + use crate::arithmetic::{adc, mac, sbb, FieldExt, Group, SqrtTables}; /// This represents an element of $\mathbb{F}_p$ where @@ -529,15 +531,8 @@ impl ff::Field for Fp { } } -#[cfg(not(target_pointer_width = "64"))] -type ReprBits = [u32; 8]; - -#[cfg(target_pointer_width = "64")] -type ReprBits = [u64; 4]; - impl ff::PrimeField for Fp { type Repr = [u8; 32]; - type ReprBits = ReprBits; const NUM_BITS: u32 = 255; const CAPACITY: u32 = 254; @@ -551,6 +546,29 @@ impl ff::PrimeField for Fp { self.to_bytes() } + fn is_odd(&self) -> bool { + self.to_bytes()[0] & 1 == 1 + } + + fn multiplicative_generator() -> Self { + GENERATOR + } + + fn root_of_unity() -> Self { + Self::ROOT_OF_UNITY + } +} + +#[cfg(all(feature = "bits", not(target_pointer_width = "64")))] +type ReprBits = [u32; 8]; + +#[cfg(all(feature = "bits", target_pointer_width = "64"))] +type ReprBits = [u64; 4]; + +#[cfg(feature = "bits")] +impl PrimeFieldBits for Fp { + type ReprBits = ReprBits; + fn to_le_bits(&self) -> FieldBits { let bytes = self.to_bytes(); @@ -577,10 +595,6 @@ impl ff::PrimeField for Fp { FieldBits::new(limbs) } - fn is_odd(&self) -> bool { - self.to_bytes()[0] & 1 == 1 - } - fn char_le_bits() -> FieldBits { #[cfg(not(target_pointer_width = "64"))] { @@ -590,14 +604,6 @@ impl ff::PrimeField for Fp { #[cfg(target_pointer_width = "64")] FieldBits::new(MODULUS.0) } - - fn multiplicative_generator() -> Self { - GENERATOR - } - - fn root_of_unity() -> Self { - Self::ROOT_OF_UNITY - } } lazy_static! { diff --git a/src/fields/fq.rs b/src/fields/fq.rs index cc8954a..3bf0b1f 100644 --- a/src/fields/fq.rs +++ b/src/fields/fq.rs @@ -1,11 +1,13 @@ use core::convert::TryInto; use core::fmt; use core::ops::{Add, Mul, Neg, Sub}; -use ff::FieldBits; use lazy_static::lazy_static; use rand::RngCore; use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; +#[cfg(feature = "bits")] +use ff::{FieldBits, PrimeFieldBits}; + use crate::arithmetic::{adc, mac, sbb, FieldExt, Group, SqrtTables}; /// This represents an element of $\mathbb{F}_q$ where @@ -529,15 +531,8 @@ impl ff::Field for Fq { } } -#[cfg(not(target_pointer_width = "64"))] -type ReprBits = [u32; 8]; - -#[cfg(target_pointer_width = "64")] -type ReprBits = [u64; 4]; - impl ff::PrimeField for Fq { type Repr = [u8; 32]; - type ReprBits = ReprBits; const NUM_BITS: u32 = 255; const CAPACITY: u32 = 254; @@ -551,6 +546,29 @@ impl ff::PrimeField for Fq { self.to_bytes() } + fn is_odd(&self) -> bool { + self.to_bytes()[0] & 1 == 1 + } + + fn multiplicative_generator() -> Self { + GENERATOR + } + + fn root_of_unity() -> Self { + Self::ROOT_OF_UNITY + } +} + +#[cfg(all(feature = "bits", not(target_pointer_width = "64")))] +type ReprBits = [u32; 8]; + +#[cfg(all(feature = "bits", target_pointer_width = "64"))] +type ReprBits = [u64; 4]; + +#[cfg(feature = "bits")] +impl PrimeFieldBits for Fq { + type ReprBits = ReprBits; + fn to_le_bits(&self) -> FieldBits { let bytes = self.to_bytes(); @@ -577,10 +595,6 @@ impl ff::PrimeField for Fq { FieldBits::new(limbs) } - fn is_odd(&self) -> bool { - self.to_bytes()[0] & 1 == 1 - } - fn char_le_bits() -> FieldBits { #[cfg(not(target_pointer_width = "64"))] { @@ -590,14 +604,6 @@ impl ff::PrimeField for Fq { #[cfg(target_pointer_width = "64")] FieldBits::new(MODULUS.0) } - - fn multiplicative_generator() -> Self { - GENERATOR - } - - fn root_of_unity() -> Self { - Self::ROOT_OF_UNITY - } } lazy_static! { From 38db1125965b12fe261eef2c08ec9ff8ae497c22 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Tue, 1 Jun 2021 23:34:22 +0100 Subject: [PATCH 5/7] Fix clippy lints --- src/arithmetic/fields.rs | 4 ++-- src/lib.rs | 7 +------ 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/src/arithmetic/fields.rs b/src/arithmetic/fields.rs index 664aade..2d774f6 100644 --- a/src/arithmetic/fields.rs +++ b/src/arithmetic/fields.rs @@ -219,8 +219,8 @@ impl SqrtTables { // Now invert gtab[3]. let mut inv: Vec = vec![1; hash_mod]; - for j in 0..256 { - let hash = hasher.hash(>ab_3[j]); + for (j, gtab_3_j) in gtab_3.iter().enumerate() { + let hash = hasher.hash(gtab_3_j); // 1 is the last value to be assigned, so this ensures there are no collisions. assert!(inv[hash] == 1); inv[hash] = ((256 - j) & 0xFF) as u8; diff --git a/src/lib.rs b/src/lib.rs index b48409d..6247a17 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,12 +2,7 @@ #![cfg_attr(docsrs, feature(doc_cfg))] #![allow(unknown_lints)] -#![allow( - clippy::op_ref, - clippy::same_item_push, - clippy::upper_case_acronyms, - clippy::unknown_clippy_lints -)] +#![allow(clippy::op_ref, clippy::same_item_push, clippy::upper_case_acronyms)] #![deny(broken_intra_doc_links)] #![deny(missing_debug_implementations)] #![deny(missing_docs)] From 17b2e5275b111111b909e5a21583981bf3dbab23 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Tue, 1 Jun 2021 23:38:30 +0100 Subject: [PATCH 6/7] Exclude contributor agreement from published crate Can't contribute to hash-pinned binaries! This file is only needed in the repo itself. --- Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.toml b/Cargo.toml index c0571f5..d55b98c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,7 @@ license-file = "LICENSE-BOSL" repository = "https://github.com/zcash/pasta_curves" documentation = "https://docs.rs/pasta_curves" readme = "README.md" +exclude = ["Contributor_Agreement"] # We are not publishing this yet. publish = false From 084d57ab101d8c114d04656813647ac78f371dea Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Tue, 1 Jun 2021 23:40:21 +0100 Subject: [PATCH 7/7] Release 0.1.0 --- CHANGELOG.md | 2 ++ Cargo.toml | 5 +---- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bafd9c5..5fea405 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,4 +6,6 @@ and this project adheres to Rust's notion of [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] + +## [0.1.0] - 2021-06-01 Initial release! diff --git a/Cargo.toml b/Cargo.toml index d55b98c..4f543de 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "pasta_curves" description = "Implementation of the Pallas and Vesta (Pasta) curve cycle" -version = "0.0.0" +version = "0.1.0" authors = [ "Sean Bowe ", "Ying Tong Lai ", @@ -15,9 +15,6 @@ documentation = "https://docs.rs/pasta_curves" readme = "README.md" exclude = ["Contributor_Agreement"] -# We are not publishing this yet. -publish = false - [package.metadata.docs.rs] all-features = true rustdoc-args = ["--cfg", "docsrs", "--html-in-header", "katex-header.html"]