mirror of
https://github.com/saymrwulf/pasta_curves-source.git
synced 2026-09-04 20:03:39 +00:00
commit
93df9c0cb9
9 changed files with 101 additions and 69 deletions
18
.github/workflows/ci.yml
vendored
18
.github/workflows/ci.yml
vendored
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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!
|
||||
|
|
|
|||
15
Cargo.toml
15
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 <sean@electriccoin.co>",
|
||||
"Ying Tong Lai <yingtong@electriccoin.co>",
|
||||
|
|
@ -13,9 +13,7 @@ license-file = "LICENSE-BOSL"
|
|||
repository = "https://github.com/zcash/pasta_curves"
|
||||
documentation = "https://docs.rs/pasta_curves"
|
||||
readme = "README.md"
|
||||
|
||||
# We are not publishing this yet.
|
||||
publish = false
|
||||
exclude = ["Contributor_Agreement"]
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
|
|
@ -39,12 +37,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"]
|
||||
|
|
|
|||
31
README.md
31
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.51** 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: y<sup>2</sup> = x<sup>3</sup> + 5 over
|
||||
`GF(0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001)`.
|
||||
|
||||
- Vesta: y<sup>2</sup> = x<sup>3</sup> + 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
|
||||
|
||||
|
|
|
|||
1
rust-toolchain
Normal file
1
rust-toolchain
Normal file
|
|
@ -0,0 +1 @@
|
|||
1.51.0
|
||||
|
|
@ -219,8 +219,8 @@ impl<F: FieldExt> SqrtTables<F> {
|
|||
|
||||
// Now invert gtab[3].
|
||||
let mut inv: Vec<u8> = 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;
|
||||
|
|
|
|||
|
|
@ -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<Self::ReprBits> {
|
||||
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<Self::ReprBits> {
|
||||
#[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! {
|
||||
|
|
|
|||
|
|
@ -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<Self::ReprBits> {
|
||||
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<Self::ReprBits> {
|
||||
#[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! {
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
Loading…
Reference in a new issue