This repository has been archived by the owner on Dec 18, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 101
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Grumpkin support for arkworks (#174)
Co-authored-by: Pratyush Mishra <pratyushmishra@berkeley.edu>
- Loading branch information
Showing
18 changed files
with
341 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,6 +20,7 @@ members = [ | |
|
||
"bn254", | ||
"ed_on_bn254", | ||
"grumpkin", | ||
|
||
"mnt4_298", | ||
"mnt6_298", | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
[package] | ||
name = "ark-grumpkin" | ||
version = "0.4.0" | ||
authors = [ "CPerezz", "arkworks contributors" ] | ||
description = "The Grumpkin prime-order elliptic curve" | ||
homepage = "https://arkworks.rs" | ||
repository = "https://github.com/arkworks-rs/curves" | ||
documentation = "https://docs.rs/ark-grumpkin/" | ||
keywords = ["cryptography", "finite-fields", "elliptic-curves" ] | ||
categories = ["cryptography"] | ||
include = ["Cargo.toml", "src"] | ||
license = "MIT/Apache-2.0" | ||
edition = "2021" | ||
|
||
[dependencies] | ||
ark-ff = { version = "0.4.0", default-features = false } | ||
ark-ec = { version = "0.4.0", default-features = false } | ||
ark-r1cs-std = { version = "0.4.0", default-features = false, optional = true } | ||
ark-std = { version = "0.4.0", default-features = false } | ||
ark-bn254 = { version = "0.4.0", path = "../bn254", default-features = false, features = [ "scalar_field", "curve" ] } | ||
|
||
[dev-dependencies] | ||
ark-relations = { version = "0.4.0", default-features = false } | ||
ark-serialize = { version = "0.4.0", default-features = false } | ||
ark-algebra-test-templates = { version = "0.4.0", default-features = false } | ||
ark-algebra-bench-templates = { version = "0.4.0", default-features = false } | ||
ark-curve-constraint-tests = { path = "../curve-constraint-tests", default-features = false } | ||
|
||
[features] | ||
default = [] | ||
std = [ "ark-std/std", "ark-ff/std", "ark-ec/std" ] | ||
r1cs = [ "ark-r1cs-std" ] | ||
|
||
[[bench]] | ||
name = "grumpkin" | ||
path = "benches/grumpkin.rs" | ||
harness = false |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../LICENSE-APACHE |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../LICENSE-MIT |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
use ark_algebra_bench_templates::*; | ||
use ark_grumpkin::{fq::Fq, fr::Fr, Projective as G}; | ||
|
||
bench!( | ||
Name = "Grumpkin", | ||
Group = G, | ||
ScalarField = Fr, | ||
PrimeBaseField = Fq, | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
modulus = 21888242871839275222246405745257275088548364400416034343698204186575808495617 | ||
|
||
assert(modulus.is_prime()) | ||
|
||
Fp = GF(modulus) | ||
|
||
generator = Fp(0); | ||
for i in range(0, 20): | ||
i = Fp(i); | ||
neg_i = Fp(-i) | ||
if not(i.is_primitive_root() or neg_i.is_primitive_root()): | ||
continue | ||
elif i.is_primitive_root(): | ||
assert(i.is_primitive_root()); | ||
print("Generator: %d" % i) | ||
generator = i | ||
break | ||
else: | ||
assert(neg_i.is_primitive_root()); | ||
print("Generator: %d" % neg_i) | ||
generator = neg_i | ||
break | ||
|
||
|
||
two_adicity = valuation(modulus - 1, 2); | ||
trace = (modulus - 1) / 2**two_adicity; | ||
two_adic_root_of_unity = generator^trace | ||
print("2-adic Root of Unity: %d " % two_adic_root_of_unity) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
modulus = 21888242871839275222246405745257275088696311157297823662689037894645226208583 | ||
|
||
assert(modulus.is_prime()) | ||
|
||
Fp = GF(modulus) | ||
|
||
generator = Fp(0); | ||
for i in range(0, 20): | ||
i = Fp(i); | ||
neg_i = Fp(-i) | ||
if not(i.is_primitive_root() or neg_i.is_primitive_root()): | ||
continue | ||
elif i.is_primitive_root(): | ||
assert(i.is_primitive_root()); | ||
print("Generator: %d" % i) | ||
generator = i | ||
break | ||
else: | ||
assert(neg_i.is_primitive_root()); | ||
print("Generator: %d" % neg_i) | ||
generator = neg_i | ||
break | ||
|
||
|
||
two_adicity = valuation(modulus - 1, 2); | ||
trace = (modulus - 1) / 2**two_adicity; | ||
two_adic_root_of_unity = generator^trace | ||
print("2-adic Root of Unity: %d " % two_adic_root_of_unity) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
use ark_r1cs_std::groups::curves::short_weierstrass::ProjectiveVar; | ||
|
||
use crate::{constraints::FBaseVar, *}; | ||
|
||
/// A group element in the Grumpkin prime-order group. | ||
pub type GVar = ProjectiveVar<GrumpkinConfig, FBaseVar>; | ||
|
||
#[test] | ||
fn test() { | ||
ark_curve_constraint_tests::curves::sw_test::<GrumpkinConfig, GVar>().unwrap(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
use ark_r1cs_std::fields::fp::FpVar; | ||
|
||
use crate::fq::Fq; | ||
|
||
/// A variable that is the R1CS equivalent of `crate::Fq`. | ||
pub type FBaseVar = FpVar<Fq>; | ||
|
||
#[test] | ||
fn test() { | ||
ark_curve_constraint_tests::fields::field_test::<_, _, FBaseVar>().unwrap(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
//! This module implements the R1CS equivalent of `ark_grumpkin`. | ||
//! | ||
//! It implements field variables for `crate::Fq`, | ||
//! and group variables for `crate::Projective`. | ||
//! | ||
//! The field underlying these constraints is `crate::Fq`. | ||
//! | ||
//! # Examples | ||
//! | ||
//! One can perform standard algebraic operations on `FBaseVar`: | ||
//! | ||
//! ``` | ||
//! # fn main() -> Result<(), ark_relations::r1cs::SynthesisError> { | ||
//! use ark_std::UniformRand; | ||
//! use ark_relations::r1cs::*; | ||
//! use ark_r1cs_std::prelude::*; | ||
//! use ark_grumpkin::{*, constraints::*}; | ||
//! | ||
//! let cs = ConstraintSystem::<Fq>::new_ref(); | ||
//! // This rng is just for test purposes; do not use it | ||
//! // in real applications. | ||
//! let mut rng = ark_std::test_rng(); | ||
//! | ||
//! // Generate some random `Fq` elements. | ||
//! let a_native = Fq::rand(&mut rng); | ||
//! let b_native = Fq::rand(&mut rng); | ||
//! | ||
//! // Allocate `a_native` and `b_native` as witness variables in `cs`. | ||
//! let a = FBaseVar::new_witness(ark_relations::ns!(cs, "generate_a"), || Ok(a_native))?; | ||
//! let b = FBaseVar::new_witness(ark_relations::ns!(cs, "generate_b"), || Ok(b_native))?; | ||
//! | ||
//! // Allocate `a_native` and `b_native` as constants in `cs`. This does not add any | ||
//! // constraints or variables. | ||
//! let a_const = FBaseVar::new_constant(ark_relations::ns!(cs, "a_as_constant"), a_native)?; | ||
//! let b_const = FBaseVar::new_constant(ark_relations::ns!(cs, "b_as_constant"), b_native)?; | ||
//! | ||
//! let one = FBaseVar::one(); | ||
//! let zero = FBaseVar::zero(); | ||
//! | ||
//! // Sanity check one + one = two | ||
//! let two = &one + &one + &zero; | ||
//! two.enforce_equal(&one.double()?)?; | ||
//! | ||
//! assert!(cs.is_satisfied()?); | ||
//! | ||
//! // Check that the value of &a + &b is correct. | ||
//! assert_eq!((&a + &b).value()?, a_native + &b_native); | ||
//! | ||
//! // Check that the value of &a * &b is correct. | ||
//! assert_eq!((&a * &b).value()?, a_native * &b_native); | ||
//! | ||
//! // Check that operations on variables and constants are equivalent. | ||
//! (&a + &b).enforce_equal(&(&a_const + &b_const))?; | ||
//! assert!(cs.is_satisfied()?); | ||
//! # Ok(()) | ||
//! # } | ||
//! ``` | ||
//! | ||
//! One can also perform standard algebraic operations on `GVar`: | ||
//! | ||
//! ``` | ||
//! # fn main() -> Result<(), ark_relations::r1cs::SynthesisError> { | ||
//! # use ark_std::UniformRand; | ||
//! # use ark_relations::r1cs::*; | ||
//! # use ark_r1cs_std::prelude::*; | ||
//! # use ark_grumpkin::{*, constraints::*}; | ||
//! | ||
//! # let cs = ConstraintSystem::<Fq>::new_ref(); | ||
//! # let mut rng = ark_std::test_rng(); | ||
//! | ||
//! // Generate some random `Projective` elements. | ||
//! let a_native = Projective::rand(&mut rng); | ||
//! let b_native = Projective::rand(&mut rng); | ||
//! | ||
//! // Allocate `a_native` and `b_native` as witness variables in `cs`. | ||
//! let a = GVar::new_witness(ark_relations::ns!(cs, "a"), || Ok(a_native))?; | ||
//! let b = GVar::new_witness(ark_relations::ns!(cs, "b"), || Ok(b_native))?; | ||
//! | ||
//! // Allocate `a_native` and `b_native` as constants in `cs`. This does not add any | ||
//! // constraints or variables. | ||
//! let a_const = GVar::new_constant(ark_relations::ns!(cs, "a_as_constant"), a_native)?; | ||
//! let b_const = GVar::new_constant(ark_relations::ns!(cs, "b_as_constant"), b_native)?; | ||
//! | ||
//! // This returns the identity. | ||
//! let zero = GVar::zero(); | ||
//! | ||
//! // Sanity check one + one = two | ||
//! let two_a = &a + &a + &zero; | ||
//! two_a.enforce_equal(&a.double()?)?; | ||
//! | ||
//! assert!(cs.is_satisfied()?); | ||
//! | ||
//! // Check that the value of &a + &b is correct. | ||
//! assert_eq!((&a + &b).value()?, a_native + &b_native); | ||
//! | ||
//! // Check that operations on variables and constants are equivalent. | ||
//! (&a + &b).enforce_equal(&(&a_const + &b_const))?; | ||
//! assert!(cs.is_satisfied()?); | ||
//! # Ok(()) | ||
//! # } | ||
//! ``` | ||
|
||
mod curves; | ||
mod fields; | ||
|
||
pub use curves::*; | ||
pub use fields::*; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
// The parameters for the curve have been taken from | ||
// https://github.com/AztecProtocol/barretenberg/blob/97ccf76c42db581a8b8f8bfbcffe8ca015a3dd22/cpp/src/barretenberg/ecc/curves/grumpkin/grumpkin.hpp | ||
|
||
use crate::{fq::Fq, fr::Fr}; | ||
use ark_ec::{ | ||
models::CurveConfig, | ||
short_weierstrass::{self as sw, SWCurveConfig}, | ||
}; | ||
use ark_ff::{AdditiveGroup, Field, MontFp, Zero}; | ||
|
||
#[cfg(test)] | ||
mod tests; | ||
|
||
#[derive(Copy, Clone, Default, PartialEq, Eq)] | ||
pub struct GrumpkinConfig; | ||
|
||
impl CurveConfig for GrumpkinConfig { | ||
type BaseField = Fq; | ||
type ScalarField = Fr; | ||
|
||
/// COFACTOR = 1 | ||
const COFACTOR: &'static [u64] = &[0x1]; | ||
|
||
/// COFACTOR_INV = 1 | ||
const COFACTOR_INV: Fr = Fr::ONE; | ||
} | ||
|
||
pub type Affine = sw::Affine<GrumpkinConfig>; | ||
pub type Projective = sw::Projective<GrumpkinConfig>; | ||
|
||
impl SWCurveConfig for GrumpkinConfig { | ||
/// COEFF_A = 0 | ||
const COEFF_A: Fq = Fq::ZERO; | ||
|
||
/// COEFF_B = -17 | ||
const COEFF_B: Fq = MontFp!("-17"); | ||
|
||
/// AFFINE_GENERATOR_COEFFS = (G1_GENERATOR_X, G1_GENERATOR_Y) | ||
const GENERATOR: Affine = Affine::new_unchecked(G_GENERATOR_X, G_GENERATOR_Y); | ||
|
||
#[inline(always)] | ||
fn mul_by_a(_: Self::BaseField) -> Self::BaseField { | ||
Self::BaseField::zero() | ||
} | ||
} | ||
|
||
/// G_GENERATOR_X = 1 | ||
/// Encoded in Montgomery form, so the value here is R mod p. | ||
pub const G_GENERATOR_X: Fq = MontFp!("1"); | ||
|
||
/// G_GENERATOR_Y = sqrt(-16) | ||
/// Encoded in Montgomery form, so the value here is 2R mod p. | ||
pub const G_GENERATOR_Y: Fq = | ||
MontFp!("17631683881184975370165255887551781615748388533673675138860"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
use crate::Projective; | ||
use ark_algebra_test_templates::*; | ||
|
||
test_group!(g1; Projective; sw); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
pub use ark_bn254::{Fr as Fq, FrConfig as FqConfig}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
pub use ark_bn254::{Fq as Fr, FqConfig as FrConfig}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
pub mod fq; | ||
pub use self::fq::*; | ||
|
||
pub mod fr; | ||
pub use self::fr::*; | ||
|
||
#[cfg(test)] | ||
mod tests; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
use crate::{Fq, Fr}; | ||
use ark_algebra_test_templates::*; | ||
|
||
test_field!(fr; Fr; mont_prime_field); | ||
test_field!(fq; Fq; mont_prime_field); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
#![cfg_attr(not(feature = "std"), no_std)] | ||
#![deny( | ||
warnings, | ||
unused, | ||
future_incompatible, | ||
nonstandard_style, | ||
rust_2018_idioms | ||
)] | ||
#![forbid(unsafe_code)] | ||
|
||
//! This library implements the prime-order curve Grumpkin, generated by | ||
//! Zachary J. Williamson from Aztec protocol. The main feature of this | ||
//! curve is that it forms a cycle with bn254, i.e. its scalar field and base | ||
//! field respectively are the base field and scalar field of bn254. | ||
//! | ||
//! | ||
//! Curve information: | ||
//! Grumpkin: | ||
//! * Base field: q = | ||
//! 21888242871839275222246405745257275088548364400416034343698204186575808495617 | ||
//! * Scalar field: r = | ||
//! 21888242871839275222246405745257275088696311157297823662689037894645226208583 | ||
//! * Curve equation: y^2 = x^3 - 17 | ||
//! * Valuation(q - 1, 2) = 28 | ||
//! * Valuation(r - 1, 2) = 1 | ||
|
||
#[cfg(feature = "r1cs")] | ||
pub mod constraints; | ||
mod curves; | ||
mod fields; | ||
|
||
pub use curves::*; | ||
pub use fields::*; |