mirror of
https://github.com/arnaucube/ark-curves-cherry-picked.git
synced 2026-01-27 14:13:46 +01:00
Compare commits
6 Commits
v0.3.0
...
reduce-gen
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5860e2a968 | ||
|
|
6805e05b50 | ||
|
|
ac58f8f92d | ||
|
|
b5c2d8eba3 | ||
|
|
129795aa4c | ||
|
|
a9cb9bfcb2 |
@@ -19,6 +19,8 @@
|
||||
|
||||
### Features
|
||||
|
||||
- [\#64](https://github.com/arkworks-rs/curves/pull/64) Implement the Bandersnatch curve, another twisted Edwards curve for BLS12-381.
|
||||
|
||||
### Improvements
|
||||
|
||||
### Bug fixes
|
||||
|
||||
@@ -15,6 +15,7 @@ members = [
|
||||
|
||||
"bls12_381",
|
||||
"ed_on_bls12_381",
|
||||
"ed_on_bls12_381_bandersnatch",
|
||||
|
||||
"bn254",
|
||||
"ed_on_bn254",
|
||||
@@ -55,3 +56,6 @@ lto = "thin"
|
||||
incremental = true
|
||||
debug-assertions = true
|
||||
debug = true
|
||||
|
||||
[patch.crates-io]
|
||||
ark-r1cs-std = { git = "https://github.com/arkworks-rs/r1cs-std", branch = "reduce-generics", optional = true, default-features = false }
|
||||
@@ -5,6 +5,7 @@ This repository contains implementations of some popular elliptic curves. The cu
|
||||
### BLS12-381 and embedded curves
|
||||
* [`ark-bls12-381`](bls12_381): Implements the BLS12-381 pairing-friendly curve
|
||||
* [`ark-ed-on-bls12-381`](ed_on_bls12_381): Implements a Twisted Edwards curve atop the scalar field of BLS12-381
|
||||
* [`ark-ed-on-bls12-381-bandersnatch`](ed_on_bls12_381_bandersnatch): Implements Bandersnatch, another Twisted Edwards curve atop the scalar field of BLS12-381
|
||||
|
||||
### BLS12-377 and related curves
|
||||
* [`ark-bls12-377`](bls12_377): Implements the BLS12-377 pairing-friendly curve
|
||||
|
||||
@@ -4,7 +4,7 @@ version = "0.3.0"
|
||||
authors = [ "arkworks contributors" ]
|
||||
description = "The BLS12-377 pairing-friendly elliptic curve"
|
||||
homepage = "https://arkworks.rs"
|
||||
repository = "https://github.com/arkworks-rs/algebra"
|
||||
repository = "https://github.com/arkworks-rs/curves"
|
||||
documentation = "https://docs.rs/ark-bls12-377/"
|
||||
keywords = ["cryptography", "finite-fields", "elliptic-curves" ]
|
||||
categories = ["cryptography"]
|
||||
|
||||
@@ -16,14 +16,8 @@ pub type G2PreparedVar = bls12::G2PreparedVar<Parameters>;
|
||||
#[test]
|
||||
fn test() {
|
||||
use ark_ec::models::bls12::Bls12Parameters;
|
||||
ark_curve_constraint_tests::curves::sw_test::<
|
||||
<Parameters as Bls12Parameters>::G1Parameters,
|
||||
G1Var,
|
||||
>()
|
||||
ark_curve_constraint_tests::curves::sw_test::<<Parameters as Bls12Parameters>::G1Parameters>()
|
||||
.unwrap();
|
||||
ark_curve_constraint_tests::curves::sw_test::<
|
||||
<Parameters as Bls12Parameters>::G2Parameters,
|
||||
G2Var,
|
||||
>()
|
||||
ark_curve_constraint_tests::curves::sw_test::<<Parameters as Bls12Parameters>::G2Parameters>()
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
@@ -130,17 +130,17 @@
|
||||
//! let pairing_result_native = Bls12_377::pairing(a_native, b_native);
|
||||
//!
|
||||
//! // Prepare `a` and `b` for pairing.
|
||||
//! let a_prep = constraints::PairingVar::prepare_g1(&a)?;
|
||||
//! let b_prep = constraints::PairingVar::prepare_g2(&b)?;
|
||||
//! let pairing_result = constraints::PairingVar::pairing(a_prep, b_prep)?;
|
||||
//! let a_prep = Bls12_377::prepare_g1(&a)?;
|
||||
//! let b_prep = Bls12_377::prepare_g2(&b)?;
|
||||
//! let pairing_result = Bls12_377::pairing_gadget(a_prep, b_prep)?;
|
||||
//!
|
||||
//! // Check that the value of &a + &b is correct.
|
||||
//! assert_eq!(pairing_result.value()?, pairing_result_native);
|
||||
//!
|
||||
//! // Check that operations on variables and constants are equivalent.
|
||||
//! let a_prep_const = constraints::PairingVar::prepare_g1(&a_const)?;
|
||||
//! let b_prep_const = constraints::PairingVar::prepare_g2(&b_const)?;
|
||||
//! let pairing_result_const = constraints::PairingVar::pairing(a_prep_const, b_prep_const)?;
|
||||
//! let a_prep_const = Bls12_377::prepare_g1(&a_const)?;
|
||||
//! let b_prep_const = Bls12_377::prepare_g2(&b_const)?;
|
||||
//! let pairing_result_const = Bls12_377::pairing_gadget(a_prep_const, b_prep_const)?;
|
||||
//! println!("Done here 3");
|
||||
//!
|
||||
//! pairing_result.enforce_equal(&pairing_result_const)?;
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
use crate::Parameters;
|
||||
|
||||
/// Specifies the constraints for computing a pairing in the BLS12-377 bilinear group.
|
||||
pub type PairingVar = ark_r1cs_std::pairing::bls12::PairingVar<Parameters>;
|
||||
pub use crate::Bls12_377;
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
use crate::Bls12_377;
|
||||
ark_curve_constraint_tests::pairing::bilinearity_test::<Bls12_377, PairingVar>().unwrap()
|
||||
ark_curve_constraint_tests::pairing::bilinearity_test::<Bls12_377>().unwrap()
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ version = "0.3.0"
|
||||
authors = [ "arkworks contributors" ]
|
||||
description = "The BLS12-381 pairing-friendly elliptic curve"
|
||||
homepage = "https://arkworks.rs"
|
||||
repository = "https://github.com/arkworks-rs/algebra"
|
||||
repository = "https://github.com/arkworks-rs/curves"
|
||||
documentation = "https://docs.rs/ark-bls12-381/"
|
||||
keywords = ["cryptography", "finite-fields", "elliptic-curves" ]
|
||||
categories = ["cryptography"]
|
||||
|
||||
@@ -4,7 +4,7 @@ version = "0.3.0"
|
||||
authors = [ "arkworks contributors" ]
|
||||
description = "The BN254 pairing-friendly elliptic curve"
|
||||
homepage = "https://arkworks.rs"
|
||||
repository = "https://github.com/arkworks-rs/algebra"
|
||||
repository = "https://github.com/arkworks-rs/curves"
|
||||
documentation = "https://docs.rs/ark-bn254/"
|
||||
keywords = ["cryptography", "finite-fields", "elliptic-curves" ]
|
||||
categories = ["cryptography"]
|
||||
|
||||
@@ -4,7 +4,7 @@ version = "0.3.0"
|
||||
authors = [ "arkworks contributors" ]
|
||||
description = "The BW6-761 pairing-friendly elliptic curve"
|
||||
homepage = "https://arkworks.rs"
|
||||
repository = "https://github.com/arkworks-rs/algebra"
|
||||
repository = "https://github.com/arkworks-rs/curves"
|
||||
documentation = "https://docs.rs/ark-bw6-761/"
|
||||
keywords = ["cryptography", "finite-fields", "elliptic-curves" ]
|
||||
categories = ["cryptography"]
|
||||
|
||||
@@ -4,7 +4,7 @@ version = "0.3.0"
|
||||
authors = [ "arkworks contributors" ]
|
||||
description = "The CP6-782 pairing-friendly elliptic curve"
|
||||
homepage = "https://arkworks.rs"
|
||||
repository = "https://github.com/arkworks-rs/algebra"
|
||||
repository = "https://github.com/arkworks-rs/curves"
|
||||
documentation = "https://docs.rs/ark-cp6-782/"
|
||||
keywords = ["cryptography", "finite-fields", "elliptic-curves" ]
|
||||
categories = ["cryptography"]
|
||||
|
||||
@@ -12,7 +12,7 @@ authors = [
|
||||
]
|
||||
description = "A benchmark library for finite fields and elliptic curves"
|
||||
homepage = "https://arkworks.rs"
|
||||
repository = "https://github.com/arkworks-rs/algebra"
|
||||
repository = "https://github.com/arkworks-rs/curves"
|
||||
documentation = "https://docs.rs/algebra/"
|
||||
keywords = ["cryptography", "finite-fields", "elliptic-curves", "pairing"]
|
||||
categories = ["cryptography"]
|
||||
|
||||
@@ -233,7 +233,8 @@ pub mod fields {
|
||||
pub mod curves {
|
||||
use ark_ec::{
|
||||
short_weierstrass_jacobian::GroupProjective as SWProjective,
|
||||
twisted_edwards_extended::GroupProjective as TEProjective, ProjectiveCurve,
|
||||
twisted_edwards_extended::GroupProjective as TEProjective, ModelParameters,
|
||||
ProjectiveCurve,
|
||||
};
|
||||
use ark_ff::{BitIteratorLE, Field, FpParameters, One, PrimeField};
|
||||
use ark_relations::r1cs::{ConstraintSystem, SynthesisError};
|
||||
@@ -241,12 +242,13 @@ pub mod curves {
|
||||
|
||||
use ark_r1cs_std::prelude::*;
|
||||
|
||||
pub fn group_test<C, ConstraintF, GG>() -> Result<(), SynthesisError>
|
||||
type ConstraintF<P> = <<P as ModelParameters>::BaseField as Field>::BasePrimeField;
|
||||
|
||||
pub fn group_test<C, ConstraintF>() -> Result<(), SynthesisError>
|
||||
where
|
||||
C: ProjectiveCurve,
|
||||
C: CurveWithVar<ConstraintF>,
|
||||
ConstraintF: Field,
|
||||
GG: CurveVar<C, ConstraintF>,
|
||||
for<'a> &'a GG: GroupOpsBounds<'a, C, GG>,
|
||||
for<'a> &'a C::Var: GroupOpsBounds<'a, C, C::Var>,
|
||||
{
|
||||
let modes = [
|
||||
AllocationMode::Input,
|
||||
@@ -259,12 +261,14 @@ pub mod curves {
|
||||
let mut rng = test_rng();
|
||||
let a_native = C::rand(&mut rng);
|
||||
let b_native = C::rand(&mut rng);
|
||||
let a = GG::new_variable(ark_relations::ns!(cs, "generate_a"), || Ok(a_native), mode)
|
||||
let a =
|
||||
C::Var::new_variable(ark_relations::ns!(cs, "generate_a"), || Ok(a_native), mode)
|
||||
.unwrap();
|
||||
let b = GG::new_variable(ark_relations::ns!(cs, "generate_b"), || Ok(b_native), mode)
|
||||
let b =
|
||||
C::Var::new_variable(ark_relations::ns!(cs, "generate_b"), || Ok(b_native), mode)
|
||||
.unwrap();
|
||||
|
||||
let zero = GG::zero();
|
||||
let zero = C::Var::zero();
|
||||
assert_eq!(zero.value()?, zero.value()?);
|
||||
|
||||
// a == a
|
||||
@@ -273,14 +277,14 @@ pub mod curves {
|
||||
assert_eq!((&a + &zero).value()?, a.value()?);
|
||||
// a - 0 = a
|
||||
assert_eq!((&a - &zero).value()?, a.value()?);
|
||||
// a - a = 0
|
||||
assert_eq!((&a - &a).value()?, zero.value()?);
|
||||
// a + b = b + a
|
||||
let a_b = &a + &b;
|
||||
let b_a = &b + &a;
|
||||
assert_eq!(a_b.value()?, b_a.value()?);
|
||||
a_b.enforce_equal(&b_a)?;
|
||||
assert!(cs.is_satisfied().unwrap());
|
||||
// a - a = 0
|
||||
assert_eq!((&a - &a).value()?, zero.value()?);
|
||||
|
||||
// (a + b) + a = a + (b + a)
|
||||
let ab_a = &a_b + &a;
|
||||
@@ -380,13 +384,15 @@ pub mod curves {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn sw_test<P, GG>() -> Result<(), SynthesisError>
|
||||
type SWVar<P> = <SWProjective<P> as CurveWithVar<ConstraintF<P>>>::Var;
|
||||
|
||||
pub fn sw_test<P>() -> Result<(), SynthesisError>
|
||||
where
|
||||
P: ark_ec::SWModelParameters,
|
||||
GG: CurveVar<SWProjective<P>, <P::BaseField as Field>::BasePrimeField>,
|
||||
for<'a> &'a GG: GroupOpsBounds<'a, SWProjective<P>, GG>,
|
||||
SWProjective<P>: CurveWithVar<ConstraintF<P>> + ProjectiveCurve,
|
||||
for<'a> &'a SWVar<P>: GroupOpsBounds<'a, SWProjective<P>, SWVar<P>>,
|
||||
{
|
||||
group_test::<SWProjective<P>, _, GG>()?;
|
||||
group_test::<SWProjective<P>, _>()?;
|
||||
let modes = [
|
||||
AllocationMode::Input,
|
||||
AllocationMode::Witness,
|
||||
@@ -405,14 +411,12 @@ pub mod curves {
|
||||
let b_affine = b.into_affine();
|
||||
|
||||
let ns = ark_relations::ns!(cs, "allocating variables");
|
||||
let mut gadget_a = GG::new_variable(cs.clone(), || Ok(a), mode)?;
|
||||
let gadget_b = GG::new_variable(cs.clone(), || Ok(b), mode)?;
|
||||
let zero = GG::zero();
|
||||
let mut gadget_a = SWVar::<P>::new_variable(cs.clone(), || Ok(a), mode)?;
|
||||
let gadget_b = SWVar::<P>::new_variable(cs.clone(), || Ok(b), mode)?;
|
||||
let zero = SWVar::<P>::zero();
|
||||
drop(ns);
|
||||
assert_eq!(gadget_a.value()?.into_affine().x, a_affine.x);
|
||||
assert_eq!(gadget_a.value()?.into_affine().y, a_affine.y);
|
||||
assert_eq!(gadget_b.value()?.into_affine().x, b_affine.x);
|
||||
assert_eq!(gadget_b.value()?.into_affine().y, b_affine.y);
|
||||
assert_eq!(gadget_a.value()?.into_affine(), a_affine);
|
||||
assert_eq!(gadget_b.value()?.into_affine(), b_affine);
|
||||
assert_eq!(cs.which_is_unsatisfied().unwrap(), None);
|
||||
|
||||
// Check addition
|
||||
@@ -453,13 +457,15 @@ pub mod curves {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn te_test<P, GG>() -> Result<(), SynthesisError>
|
||||
type TEVar<P> = <TEProjective<P> as CurveWithVar<ConstraintF<P>>>::Var;
|
||||
|
||||
pub fn te_test<P>() -> Result<(), SynthesisError>
|
||||
where
|
||||
P: ark_ec::TEModelParameters,
|
||||
GG: CurveVar<TEProjective<P>, <P::BaseField as Field>::BasePrimeField>,
|
||||
for<'a> &'a GG: GroupOpsBounds<'a, TEProjective<P>, GG>,
|
||||
TEProjective<P>: CurveWithVar<ConstraintF<P>> + ProjectiveCurve,
|
||||
for<'a> &'a TEVar<P>: GroupOpsBounds<'a, TEProjective<P>, TEVar<P>>,
|
||||
{
|
||||
group_test::<TEProjective<P>, _, GG>()?;
|
||||
group_test::<TEProjective<P>, _>()?;
|
||||
let modes = [
|
||||
AllocationMode::Input,
|
||||
AllocationMode::Witness,
|
||||
@@ -478,14 +484,12 @@ pub mod curves {
|
||||
let b_affine = b.into_affine();
|
||||
|
||||
let ns = ark_relations::ns!(cs, "allocating variables");
|
||||
let mut gadget_a = GG::new_variable(cs.clone(), || Ok(a), mode)?;
|
||||
let gadget_b = GG::new_variable(cs.clone(), || Ok(b), mode)?;
|
||||
let mut gadget_a = TEVar::<P>::new_variable(cs.clone(), || Ok(a), mode)?;
|
||||
let gadget_b = TEVar::<P>::new_variable(cs.clone(), || Ok(b), mode)?;
|
||||
drop(ns);
|
||||
|
||||
assert_eq!(gadget_a.value()?.into_affine().x, a_affine.x);
|
||||
assert_eq!(gadget_a.value()?.into_affine().y, a_affine.y);
|
||||
assert_eq!(gadget_b.value()?.into_affine().x, b_affine.x);
|
||||
assert_eq!(gadget_b.value()?.into_affine().y, b_affine.y);
|
||||
assert_eq!(gadget_a.value()?.into_affine(), a_affine);
|
||||
assert_eq!(gadget_b.value()?.into_affine(), b_affine);
|
||||
assert_eq!(cs.which_is_unsatisfied()?, None);
|
||||
|
||||
// Check addition
|
||||
@@ -527,16 +531,21 @@ pub mod curves {
|
||||
pub mod pairing {
|
||||
use ark_ec::{PairingEngine, ProjectiveCurve};
|
||||
use ark_ff::{BitIteratorLE, Field, PrimeField};
|
||||
use ark_r1cs_std::prelude::*;
|
||||
use ark_r1cs_std::{fields::fp::FpVar, prelude::*};
|
||||
use ark_relations::r1cs::{ConstraintSystem, SynthesisError};
|
||||
use ark_std::{test_rng, vec::Vec, UniformRand};
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn bilinearity_test<E: PairingEngine, P: PairingVar<E>>() -> Result<(), SynthesisError>
|
||||
pub fn bilinearity_test<P: PairingGadget>() -> Result<(), SynthesisError>
|
||||
where
|
||||
for<'a> &'a P::G1Var: GroupOpsBounds<'a, E::G1Projective, P::G1Var>,
|
||||
for<'a> &'a P::G2Var: GroupOpsBounds<'a, E::G2Projective, P::G2Var>,
|
||||
for<'a> &'a P::GTVar: FieldOpsBounds<'a, E::Fqk, P::GTVar>,
|
||||
for<'a> &'a P::G1Var: GroupOpsBounds<'a, P::G1Projective, P::G1Var>,
|
||||
for<'a> &'a P::G2Var: GroupOpsBounds<'a, P::G2Projective, P::G2Var>,
|
||||
for<'a> &'a P::GTVar: FieldOpsBounds<'a, P::Fqk, P::GTVar>,
|
||||
P::Fq: FieldWithVar<Var = FpVar<P::Fq>>,
|
||||
P::Fqe: FieldWithVar,
|
||||
P::Fqk: FieldWithVar<Var = P::GTVar>,
|
||||
P::G1Projective: CurveWithVar<P::Fq, Var = P::G1Var>,
|
||||
P::G2Projective: CurveWithVar<P::Fq, Var = P::G2Var>,
|
||||
{
|
||||
let modes = [
|
||||
AllocationMode::Input,
|
||||
@@ -544,12 +553,12 @@ pub mod pairing {
|
||||
AllocationMode::Constant,
|
||||
];
|
||||
for &mode in &modes {
|
||||
let cs = ConstraintSystem::<E::Fq>::new_ref();
|
||||
let cs = ConstraintSystem::<P::Fq>::new_ref();
|
||||
|
||||
let mut rng = test_rng();
|
||||
let a = E::G1Projective::rand(&mut rng);
|
||||
let b = E::G2Projective::rand(&mut rng);
|
||||
let s = E::Fr::rand(&mut rng);
|
||||
let a = P::G1Projective::rand(&mut rng);
|
||||
let b = P::G2Projective::rand(&mut rng);
|
||||
let s = P::Fr::rand(&mut rng);
|
||||
|
||||
let mut sa = a;
|
||||
sa *= s;
|
||||
@@ -571,16 +580,16 @@ pub mod pairing {
|
||||
|
||||
let (ans1_g, ans1_n) = {
|
||||
let _ml_constraints = cs.num_constraints();
|
||||
let ml_g = P::miller_loop(&[sa_prep_g], &[b_prep_g.clone()])?;
|
||||
let ml_g = P::miller_loop_gadget(&[sa_prep_g], &[b_prep_g.clone()])?;
|
||||
let _fe_constraints = cs.num_constraints();
|
||||
let ans_g = P::final_exponentiation(&ml_g)?;
|
||||
let ans_n = E::pairing(sa, b);
|
||||
let ans_g = P::final_exponentiation_gadget(&ml_g)?;
|
||||
let ans_n = <P as PairingEngine>::pairing(sa, b);
|
||||
(ans_g, ans_n)
|
||||
};
|
||||
|
||||
let (ans2_g, ans2_n) = {
|
||||
let ans_g = P::pairing(a_prep_g.clone(), sb_prep_g)?;
|
||||
let ans_n = E::pairing(a, sb);
|
||||
let ans_g = P::pairing_gadget(a_prep_g.clone(), sb_prep_g)?;
|
||||
let ans_n = <P as PairingEngine>::pairing(a, sb);
|
||||
(ans_g, ans_n)
|
||||
};
|
||||
|
||||
@@ -589,8 +598,8 @@ pub mod pairing {
|
||||
.map(Boolean::constant)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let mut ans_g = P::pairing(a_prep_g, b_prep_g)?;
|
||||
let mut ans_n = E::pairing(a, b);
|
||||
let mut ans_g = P::pairing_gadget(a_prep_g, b_prep_g)?;
|
||||
let mut ans_n = <P as PairingEngine>::pairing(a, b);
|
||||
ans_n = ans_n.pow(s.into_repr());
|
||||
ans_g = ans_g.pow_le(&s_iter)?;
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ version = "0.3.0"
|
||||
authors = [ "arkworks contributors" ]
|
||||
description = "A Twisted Edwards curve defined over the scalar field of the BLS12-377 curve"
|
||||
homepage = "https://arkworks.rs"
|
||||
repository = "https://github.com/arkworks-rs/algebra"
|
||||
repository = "https://github.com/arkworks-rs/curves"
|
||||
documentation = "https://docs.rs/ark-ed-on-bls12-377/"
|
||||
keywords = ["cryptography", "finite-fields", "elliptic-curves" ]
|
||||
categories = ["cryptography"]
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
use crate::*;
|
||||
use ark_r1cs_std::groups::curves::twisted_edwards::AffineVar;
|
||||
|
||||
use crate::constraints::FqVar;
|
||||
|
||||
/// A variable that is the R1CS equivalent of `crate::EdwardsAffine`.
|
||||
pub type EdwardsVar = AffineVar<EdwardsParameters, FqVar>;
|
||||
pub type EdwardsVar = AffineVar<EdwardsParameters>;
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
ark_curve_constraint_tests::curves::te_test::<EdwardsParameters, EdwardsVar>().unwrap();
|
||||
ark_curve_constraint_tests::curves::te_test::<EdwardsParameters>().unwrap();
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ version = "0.3.0"
|
||||
authors = [ "arkworks contributors" ]
|
||||
description = "A Twisted Edwards curve defined over the scalar field of the BLS12-381 curve"
|
||||
homepage = "https://arkworks.rs"
|
||||
repository = "https://github.com/arkworks-rs/algebra"
|
||||
repository = "https://github.com/arkworks-rs/curves"
|
||||
documentation = "https://docs.rs/ark-ed-on-bls12-381/"
|
||||
keywords = ["cryptography", "finite-fields", "elliptic-curves" ]
|
||||
categories = ["cryptography"]
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
use crate::*;
|
||||
use ark_r1cs_std::groups::curves::twisted_edwards::AffineVar;
|
||||
|
||||
use crate::constraints::FqVar;
|
||||
|
||||
/// A variable that is the R1CS equivalent of `crate::EdwardsAffine`.
|
||||
pub type EdwardsVar = AffineVar<EdwardsParameters, FqVar>;
|
||||
pub type EdwardsVar = AffineVar<EdwardsParameters>;
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
ark_curve_constraint_tests::curves::te_test::<_, EdwardsVar>().unwrap();
|
||||
ark_curve_constraint_tests::curves::te_test::<EdwardsParameters>().unwrap();
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#![forbid(unsafe_code)]
|
||||
|
||||
//! This library implements a twisted Edwards curve whose base field is the scalar field of the
|
||||
//! curve BLS12-377. This allows defining cryptographic primitives that use elliptic curves over
|
||||
//! curve BLS12-381. This allows defining cryptographic primitives that use elliptic curves over
|
||||
//! the scalar field of the latter curve. This curve was generated by Sean Bowe, and is also known
|
||||
//! as [Jubjub](https://github.com/zkcrypto/jubjub).
|
||||
//!
|
||||
|
||||
34
ed_on_bls12_381_bandersnatch/Cargo.toml
Normal file
34
ed_on_bls12_381_bandersnatch/Cargo.toml
Normal file
@@ -0,0 +1,34 @@
|
||||
[package]
|
||||
name = "ark-ed-on-bls12-381-bandersnatch"
|
||||
version = "0.1.0"
|
||||
authors = [ "zhenfei zhang", "arkworks contributors" ]
|
||||
description = "Bandersnatch: a curve defined over the scalar field of the BLS12-381 curve"
|
||||
repository = "https://github.com/zhenfeizhang/bandersnatch-rust"
|
||||
keywords = ["cryptography", "finite-fields", "elliptic-curves" ]
|
||||
categories = ["cryptography"]
|
||||
include = ["Cargo.toml", "src", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
|
||||
license = "MIT/Apache-2.0"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
ark-ff = { version = "^0.3.0", default-features = false }
|
||||
ark-ec = { version = "^0.3.0", default-features = false }
|
||||
ark-std = { version = "^0.3.0", default-features = false }
|
||||
ark-r1cs-std = { version = "^0.3.0", default-features = false, optional = true }
|
||||
ark-bls12-381 = { version = "^0.3.0", default-features = false, features = [ "scalar_field" ] }
|
||||
|
||||
[dev-dependencies]
|
||||
ark-relations = { version = "^0.3.0", default-features = false }
|
||||
ark-serialize = { version = "^0.3.0", default-features = false }
|
||||
ark-algebra-test-templates = { version = "^0.3.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",
|
||||
"ark-bls12-381/std"
|
||||
]
|
||||
r1cs = ["ark-r1cs-std"]
|
||||
10
ed_on_bls12_381_bandersnatch/src/constraints/curves.rs
Normal file
10
ed_on_bls12_381_bandersnatch/src/constraints/curves.rs
Normal file
@@ -0,0 +1,10 @@
|
||||
use crate::*;
|
||||
use ark_r1cs_std::groups::curves::twisted_edwards::AffineVar;
|
||||
|
||||
/// A variable that is the R1CS equivalent of `crate::EdwardsAffine`.
|
||||
pub type EdwardsVar = AffineVar<EdwardsParameters>;
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
ark_curve_constraint_tests::curves::te_test::<EdwardsParameters>().unwrap();
|
||||
}
|
||||
9
ed_on_bls12_381_bandersnatch/src/constraints/fields.rs
Normal file
9
ed_on_bls12_381_bandersnatch/src/constraints/fields.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
use ark_r1cs_std::fields::fp::FpVar;
|
||||
|
||||
/// A variable that is the R1CS equivalent of `crate::Fq`.
|
||||
pub type FqVar = FpVar<crate::Fq>;
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
ark_curve_constraint_tests::fields::field_test::<_, _, FqVar>().unwrap();
|
||||
}
|
||||
107
ed_on_bls12_381_bandersnatch/src/constraints/mod.rs
Normal file
107
ed_on_bls12_381_bandersnatch/src/constraints/mod.rs
Normal file
@@ -0,0 +1,107 @@
|
||||
//! This module implements the R1CS equivalent of `ark_bandersnatch`.
|
||||
//!
|
||||
//! It implements field variables for `crate::Fq`,
|
||||
//! and group variables for `crate::GroupProjective`.
|
||||
//!
|
||||
//! The field underlying these constraints is `crate::Fq`.
|
||||
//!
|
||||
//! # Examples
|
||||
//!
|
||||
//! One can perform standard algebraic operations on `FqVar`:
|
||||
//!
|
||||
//! ```
|
||||
//! # fn main() -> Result<(), ark_relations::r1cs::SynthesisError> {
|
||||
//! use ark_std::UniformRand;
|
||||
//! use ark_relations::r1cs::*;
|
||||
//! use ark_r1cs_std::prelude::*;
|
||||
//! use ark_ed_on_bls12_381_bandersnatch::{*, 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 = FqVar::new_witness(ark_relations::ns!(cs, "generate_a"), || Ok(a_native))?;
|
||||
//! let b = FqVar::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 = FqVar::new_constant(ark_relations::ns!(cs, "a_as_constant"), a_native)?;
|
||||
//! let b_const = FqVar::new_constant(ark_relations::ns!(cs, "b_as_constant"), b_native)?;
|
||||
//!
|
||||
//! let one = FqVar::one();
|
||||
//! let zero = FqVar::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 `EdwardsVar`:
|
||||
//!
|
||||
//! ```
|
||||
//! # fn main() -> Result<(), ark_relations::r1cs::SynthesisError> {
|
||||
//! # use ark_std::UniformRand;
|
||||
//! # use ark_relations::r1cs::*;
|
||||
//! # use ark_r1cs_std::prelude::*;
|
||||
//! # use ark_ed_on_bls12_381_bandersnatch::{*, constraints::*};
|
||||
//!
|
||||
//! # let cs = ConstraintSystem::<Fq>::new_ref();
|
||||
//! # let mut rng = ark_std::test_rng();
|
||||
//!
|
||||
//! // Generate some random `Edwards` elements.
|
||||
//! let a_native = EdwardsProjective::rand(&mut rng);
|
||||
//! let b_native = EdwardsProjective::rand(&mut rng);
|
||||
//!
|
||||
//! // Allocate `a_native` and `b_native` as witness variables in `cs`.
|
||||
//! let a = EdwardsVar::new_witness(ark_relations::ns!(cs, "a"), || Ok(a_native))?;
|
||||
//! let b = EdwardsVar::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 = EdwardsVar::new_constant(ark_relations::ns!(cs, "a_as_constant"), a_native)?;
|
||||
//! let b_const = EdwardsVar::new_constant(ark_relations::ns!(cs, "b_as_constant"), b_native)?;
|
||||
//!
|
||||
//! // This returns the identity of `Edwards`.
|
||||
//! let zero = EdwardsVar::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::*;
|
||||
94
ed_on_bls12_381_bandersnatch/src/curves/mod.rs
Normal file
94
ed_on_bls12_381_bandersnatch/src/curves/mod.rs
Normal file
@@ -0,0 +1,94 @@
|
||||
use crate::{Fq, Fr};
|
||||
use ark_ec::{
|
||||
models::{ModelParameters, MontgomeryModelParameters, TEModelParameters},
|
||||
twisted_edwards_extended::{GroupAffine, GroupProjective},
|
||||
};
|
||||
use ark_ff::{field_new, Field};
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
pub type EdwardsAffine = GroupAffine<EdwardsParameters>;
|
||||
pub type EdwardsProjective = GroupProjective<EdwardsParameters>;
|
||||
|
||||
/// `banersnatch` is a twisted Edwards curve. These curves have equations of the
|
||||
/// form: ax² + y² = 1 - dx²y².
|
||||
/// over some base finite field Fq.
|
||||
///
|
||||
/// banersnatch's curve equation: -5x² + y² = 1 - dx²y²
|
||||
///
|
||||
/// q = 52435875175126190479447740508185965837690552500527637822603658699938581184513.
|
||||
///
|
||||
/// a = 52435875175126190479447740508185965837690552500527637822603658699938581184508.
|
||||
/// d = (138827208126141220649022263972958607803/
|
||||
/// 171449701953573178309673572579671231137) mod q
|
||||
/// = 45022363124591815672509500913686876175488063829319466900776701791074614335719.
|
||||
///
|
||||
/// Sage script to calculate these:
|
||||
///
|
||||
/// ```text
|
||||
/// q = 52435875175126190479447740508185965837690552500527637822603658699938581184513
|
||||
/// Fq = GF(q)
|
||||
/// d = (Fq(138827208126141220649022263972958607803)/Fq(171449701953573178309673572579671231137))
|
||||
/// ```
|
||||
/// These parameters and the sage script obtained from:
|
||||
/// <https://github.com/asanso/Bandersnatch/>
|
||||
#[derive(Clone, Default, PartialEq, Eq)]
|
||||
pub struct EdwardsParameters;
|
||||
|
||||
impl ModelParameters for EdwardsParameters {
|
||||
type BaseField = Fq;
|
||||
type ScalarField = Fr;
|
||||
}
|
||||
|
||||
impl TEModelParameters for EdwardsParameters {
|
||||
/// COEFF_A = -5
|
||||
#[rustfmt::skip]
|
||||
const COEFF_A: Fq = field_new!(Fq, "-5");
|
||||
|
||||
/// COEFF_D = (138827208126141220649022263972958607803/
|
||||
/// 171449701953573178309673572579671231137) mod q
|
||||
#[rustfmt::skip]
|
||||
const COEFF_D: Fq = field_new!(Fq, "45022363124591815672509500913686876175488063829319466900776701791074614335719");
|
||||
|
||||
/// COFACTOR = 4
|
||||
const COFACTOR: &'static [u64] = &[4];
|
||||
|
||||
/// COFACTOR^(-1) mod r =
|
||||
/// 9831726595336160714896451345284868594481866920080427688839802480047265754601
|
||||
#[rustfmt::skip]
|
||||
const COFACTOR_INV: Fr = field_new!(Fr, "9831726595336160714896451345284868594481866920080427688839802480047265754601");
|
||||
|
||||
/// AFFINE_GENERATOR_COEFFS = (GENERATOR_X, GENERATOR_Y)
|
||||
const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField) = (GENERATOR_X, GENERATOR_Y);
|
||||
|
||||
type MontgomeryModelParameters = EdwardsParameters;
|
||||
|
||||
/// Multiplication by `a` is multiply by `-5`.
|
||||
#[inline(always)]
|
||||
fn mul_by_a(elem: &Self::BaseField) -> Self::BaseField {
|
||||
let t = (*elem).double().double();
|
||||
-(t + *elem)
|
||||
}
|
||||
}
|
||||
|
||||
impl MontgomeryModelParameters for EdwardsParameters {
|
||||
/// COEFF_A = 29978822694968839326280996386011761570173833766074948509196803838190355340952
|
||||
#[rustfmt::skip]
|
||||
const COEFF_A: Fq = field_new!(Fq, "29978822694968839326280996386011761570173833766074948509196803838190355340952");
|
||||
/// COEFF_B = 25465760566081946422412445027709227188579564747101592991722834452325077642517
|
||||
#[rustfmt::skip]
|
||||
const COEFF_B: Fq = field_new!(Fq, "25465760566081946422412445027709227188579564747101592991722834452325077642517");
|
||||
|
||||
type TEModelParameters = EdwardsParameters;
|
||||
}
|
||||
|
||||
// using the generator from bench.py (in affine form)
|
||||
// P = BandersnatchPoint(
|
||||
// 13738737789055671334382939318077718462576533426798874551591468520593954805549,
|
||||
// 11575885077368931610486103676191793534029821920164915325066801506752632626968,
|
||||
// 14458123306641001284399433086015669988340559992755622870694102351476334505845,
|
||||
// C)
|
||||
#[rustfmt::skip]
|
||||
const GENERATOR_X: Fq = field_new!(Fq, "29627151942733444043031429156003786749302466371339015363120350521834195802525");
|
||||
#[rustfmt::skip]
|
||||
const GENERATOR_Y: Fq = field_new!(Fq, "27488387519748396681411951718153463804682561779047093991696427532072116857978");
|
||||
103
ed_on_bls12_381_bandersnatch/src/curves/tests.rs
Normal file
103
ed_on_bls12_381_bandersnatch/src/curves/tests.rs
Normal file
@@ -0,0 +1,103 @@
|
||||
use crate::*;
|
||||
use ark_algebra_test_templates::{curves::*, groups::*};
|
||||
use ark_ec::{AffineCurve, ProjectiveCurve};
|
||||
use ark_ff::{bytes::FromBytes, Zero};
|
||||
use ark_std::{rand::Rng, str::FromStr, test_rng};
|
||||
|
||||
#[test]
|
||||
fn test_projective_curve() {
|
||||
curve_tests::<EdwardsProjective>();
|
||||
|
||||
edwards_tests::<EdwardsParameters>();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_projective_group() {
|
||||
let mut rng = test_rng();
|
||||
let a = rng.gen();
|
||||
let b = rng.gen();
|
||||
for _i in 0..100 {
|
||||
group_test::<EdwardsProjective>(a, b);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_affine_group() {
|
||||
let mut rng = test_rng();
|
||||
let a: EdwardsAffine = rng.gen();
|
||||
let b: EdwardsAffine = rng.gen();
|
||||
for _i in 0..100 {
|
||||
group_test::<EdwardsAffine>(a, b);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_generator() {
|
||||
let generator = EdwardsAffine::prime_subgroup_generator();
|
||||
assert!(generator.is_on_curve());
|
||||
assert!(generator.is_in_correct_subgroup_assuming_on_curve());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_conversion() {
|
||||
let mut rng = test_rng();
|
||||
let a: EdwardsAffine = rng.gen();
|
||||
let b: EdwardsAffine = rng.gen();
|
||||
let a_b = {
|
||||
use ark_ec::group::Group;
|
||||
(a + &b).double().double()
|
||||
};
|
||||
let a_b2 = (a.into_projective() + &b.into_projective())
|
||||
.double()
|
||||
.double();
|
||||
assert_eq!(a_b, a_b2.into_affine());
|
||||
assert_eq!(a_b.into_projective(), a_b2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_scalar_multiplication() {
|
||||
let f1 = Fr::from_str(
|
||||
"4257185345094557079734489188109952172285839137338142340240392707284963971010",
|
||||
)
|
||||
.unwrap();
|
||||
let f2 = Fr::from_str(
|
||||
"1617998875791656082457755819308421023664764572929977389209373068350490665160",
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let g = EdwardsAffine::from_str(
|
||||
"(29627151942733444043031429156003786749302466371339015363120350521834195802525, \
|
||||
27488387519748396681411951718153463804682561779047093991696427532072116857978)",
|
||||
)
|
||||
.unwrap();
|
||||
let f1f2g = EdwardsAffine::from_str(
|
||||
"(16530491029447613915334753043669938793793987372416328257719459807614119987301, \
|
||||
42481140308370805476764840229335460092474682686441442216596889726548353970772)",
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert!(!g.is_zero());
|
||||
assert!(!f1f2g.is_zero());
|
||||
|
||||
let f1g = g.mul(f1).into_affine();
|
||||
assert_eq!(g.mul(f1 * &f2).into_affine(), f1f2g);
|
||||
assert_eq!(f1g.mul(f2).into_affine(), f1f2g);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bytes() {
|
||||
let g_from_repr = EdwardsAffine::from_str(
|
||||
"(29627151942733444043031429156003786749302466371339015363120350521834195802525, \
|
||||
27488387519748396681411951718153463804682561779047093991696427532072116857978)",
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let g_bytes = ark_ff::to_bytes![g_from_repr].unwrap();
|
||||
let g = EdwardsAffine::read(g_bytes.as_slice()).unwrap();
|
||||
assert_eq!(g_from_repr, g);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_montgomery_conversion() {
|
||||
montgomery_conversion_test::<EdwardsParameters>();
|
||||
}
|
||||
1
ed_on_bls12_381_bandersnatch/src/fields/fq.rs
Normal file
1
ed_on_bls12_381_bandersnatch/src/fields/fq.rs
Normal file
@@ -0,0 +1 @@
|
||||
pub use ark_bls12_381::{Fr as Fq, FrParameters as FqParameters};
|
||||
115
ed_on_bls12_381_bandersnatch/src/fields/fr.rs
Normal file
115
ed_on_bls12_381_bandersnatch/src/fields/fr.rs
Normal file
@@ -0,0 +1,115 @@
|
||||
use ark_ff::{
|
||||
biginteger::BigInteger256 as BigInteger,
|
||||
fields::{FftParameters, Fp256, Fp256Parameters, FpParameters},
|
||||
};
|
||||
|
||||
pub type Fr = Fp256<FrParameters>;
|
||||
|
||||
pub struct FrParameters;
|
||||
|
||||
impl Fp256Parameters for FrParameters {}
|
||||
impl FftParameters for FrParameters {
|
||||
type BigInt = BigInteger;
|
||||
|
||||
/// Let `N` be the size of the multiplicative group defined by the field.
|
||||
/// Then `TWO_ADICITY` is the two-adicity of `N`, i.e. the integer `s`
|
||||
/// such that `N = 2^s * t` for some odd integer `t`.
|
||||
const TWO_ADICITY: u32 = 5;
|
||||
|
||||
/// 2^s root of unity computed by GENERATOR^t
|
||||
/// 4740934665446857387895054948191089665295030226009829406950782728666658007874
|
||||
#[rustfmt::skip]
|
||||
const TWO_ADIC_ROOT_OF_UNITY: BigInteger = BigInteger([
|
||||
0xa4dcdba087826b42,
|
||||
0x6e4ab162f57f862a,
|
||||
0xabc5492749348d6a,
|
||||
0xa7b462035f8c169,
|
||||
]);
|
||||
}
|
||||
impl FpParameters for FrParameters {
|
||||
/// The modulus of the field.
|
||||
/// MODULUS = 13108968793781547619861935127046491459309155893440570251786403306729687672801.
|
||||
#[rustfmt::skip]
|
||||
const MODULUS: BigInteger = BigInteger([
|
||||
0x74fd06b52876e7e1,
|
||||
0xff8f870074190471,
|
||||
0x0cce760202687600,
|
||||
0x1cfb69d4ca675f52,
|
||||
]);
|
||||
|
||||
/// The number of bits needed to represent the `Self::MODULUS`.
|
||||
const MODULUS_BITS: u32 = 253;
|
||||
|
||||
/// The number of bits that can be reliably stored.
|
||||
/// (Should equal `SELF::MODULUS_BITS - 1`)
|
||||
const CAPACITY: u32 = Self::MODULUS_BITS - 1;
|
||||
|
||||
/// The number of bits that must be shaved from the beginning of
|
||||
/// the representation when randomly sampling.
|
||||
const REPR_SHAVE_BITS: u32 = 4;
|
||||
|
||||
/// Let `M` be the power of 2^64 nearest to `Self::MODULUS_BITS`. Then
|
||||
/// `R = M % Self::MODULUS`.
|
||||
/// R = 10920338887063814464675503992315976178796737518116002025166357554075628257528
|
||||
#[rustfmt::skip]
|
||||
const R: BigInteger = BigInteger([
|
||||
0x5817ca56bc48c0f8,
|
||||
0x0383c7fc5f37dc74,
|
||||
0x998c4fefecbc4ff8,
|
||||
0x1824b159acc5056f,
|
||||
]);
|
||||
|
||||
/// R2 = R^2 % Self::MODULUS
|
||||
/// R2 = 4932290691328759802879919559207542894238895193980447506221046538067943049163
|
||||
#[rustfmt::skip]
|
||||
const R2: BigInteger = BigInteger([
|
||||
0xdbb4f5d658db47cb,
|
||||
0x40fa7ca27fecb938,
|
||||
0xaa9e6daec0055cea,
|
||||
0xae793ddb14aec7d
|
||||
]);
|
||||
|
||||
/// INV = -MODULUS^{-1} mod 2^64
|
||||
/// INV = 17410672245482742751
|
||||
const INV: u64 = 0xf19f22295cc063df;
|
||||
|
||||
/// A multiplicative generator of the field.
|
||||
/// `Self::GENERATOR` is an element having multiplicative order
|
||||
/// `Self::MODULUS - 1`.
|
||||
/// n = 9962557815892774795293348142308860067333132192265356416788884706064406244838
|
||||
#[rustfmt::skip]
|
||||
const GENERATOR: BigInteger = BigInteger([
|
||||
0x56b6f3ab7b616de6,
|
||||
0x114f419d6c9083e5,
|
||||
0xbf518d217780c4b9,
|
||||
0x16069b9f45dbce7f,
|
||||
]);
|
||||
|
||||
/// (Self::MODULUS - 1) / 2
|
||||
/// 6554484396890773809930967563523245729654577946720285125893201653364843836400
|
||||
const MODULUS_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([
|
||||
0xba7e835a943b73f0,
|
||||
0x7fc7c3803a0c8238,
|
||||
0x06673b0101343b00,
|
||||
0xe7db4ea6533afa9,
|
||||
]);
|
||||
|
||||
/// t for 2^s * t = MODULUS - 1, and t coprime to 2.
|
||||
/// t = 409655274805673363120685472720202858103411121670017820368325103335302739775
|
||||
/// = (modulus-1)/2^5
|
||||
const T: BigInteger = BigInteger([
|
||||
0x8ba7e835a943b73f,
|
||||
0x07fc7c3803a0c823,
|
||||
0x906673b0101343b0,
|
||||
0xe7db4ea6533afa,
|
||||
]);
|
||||
|
||||
/// (t - 1) / 2
|
||||
/// = 204827637402836681560342736360101429051705560835008910184162551667651369887
|
||||
const T_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([
|
||||
0xc5d3f41ad4a1db9f,
|
||||
0x03fe3e1c01d06411,
|
||||
0x483339d80809a1d8,
|
||||
0x73eda753299d7d,
|
||||
]);
|
||||
}
|
||||
8
ed_on_bls12_381_bandersnatch/src/fields/mod.rs
Normal file
8
ed_on_bls12_381_bandersnatch/src/fields/mod.rs
Normal file
@@ -0,0 +1,8 @@
|
||||
pub mod fq;
|
||||
pub mod fr;
|
||||
|
||||
pub use fq::*;
|
||||
pub use fr::*;
|
||||
|
||||
#[cfg(all(feature = "ed_on_bls12_381_bandersnatch", test))]
|
||||
mod tests;
|
||||
423
ed_on_bls12_381_bandersnatch/src/fields/tests.rs
Normal file
423
ed_on_bls12_381_bandersnatch/src/fields/tests.rs
Normal file
@@ -0,0 +1,423 @@
|
||||
use crate::{Fq, Fr};
|
||||
use ark_algebra_test_templates::fields::*;
|
||||
use ark_ff::{
|
||||
biginteger::BigInteger256 as BigInteger,
|
||||
bytes::{FromBytes, ToBytes},
|
||||
fields::{Field, LegendreSymbol::*, SquareRootField},
|
||||
One, Zero,
|
||||
};
|
||||
use ark_std::{rand::Rng, str::FromStr, test_rng};
|
||||
|
||||
#[test]
|
||||
fn test_fr() {
|
||||
let mut rng = test_rng();
|
||||
let a: Fr = rng.gen();
|
||||
let b: Fr = rng.gen();
|
||||
field_test(a, b);
|
||||
primefield_test::<Fr>();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq() {
|
||||
let mut rng = test_rng();
|
||||
let a: Fq = rng.gen();
|
||||
let b: Fq = rng.gen();
|
||||
field_test(a, b);
|
||||
primefield_test::<Fq>();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq_add() {
|
||||
let f1 = Fq::from_str(
|
||||
"18386742314266644595564329008376577163854043021652781768352795308532764650733",
|
||||
)
|
||||
.unwrap();
|
||||
let f2 = Fq::from_str(
|
||||
"39786307610986038981023499868190793548353538256264351797285876981647142458383",
|
||||
)
|
||||
.unwrap();
|
||||
let f3 = Fq::from_str(
|
||||
"5737174750126493097140088368381404874517028777389495743035013590241325924603",
|
||||
)
|
||||
.unwrap();
|
||||
assert!(!f1.is_zero());
|
||||
assert!(!f2.is_zero());
|
||||
assert!(!f3.is_zero());
|
||||
assert_eq!(f1 + &f2, f3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq_add_one() {
|
||||
let f1 = Fq::from_str(
|
||||
"4946875394261337176810256604189376311946643975348516311606738923340201185904",
|
||||
)
|
||||
.unwrap();
|
||||
let f2 = Fq::from_str(
|
||||
"4946875394261337176810256604189376311946643975348516311606738923340201185905",
|
||||
)
|
||||
.unwrap();
|
||||
assert!(!f1.is_zero());
|
||||
assert!(!f2.is_zero());
|
||||
assert_eq!(f1 + &Fq::one(), f2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq_mul() {
|
||||
let f1 = Fq::from_str(
|
||||
"24703123148064348394273033316595937198355721297494556079070134653139656190956",
|
||||
)
|
||||
.unwrap();
|
||||
let f2 = Fq::from_str(
|
||||
"38196797080882758914424853878212529985425118523754343117256179679117054302131",
|
||||
)
|
||||
.unwrap();
|
||||
let f3 = Fq::from_str(
|
||||
"38057113854472161555556064369220825628027487067886761874351491955834635348140",
|
||||
)
|
||||
.unwrap();
|
||||
assert!(!f1.is_zero());
|
||||
assert!(!f2.is_zero());
|
||||
assert!(!f3.is_zero());
|
||||
assert_eq!(f1 * &f2, f3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq_triple_mul() {
|
||||
let f1 = Fq::from_str(
|
||||
"23834398828139479510988224171342199299644042568628082836691700490363123893905",
|
||||
)
|
||||
.unwrap();
|
||||
let f2 = Fq::from_str(
|
||||
"48343809612844640454129919255697536258606705076971130519928764925719046689317",
|
||||
)
|
||||
.unwrap();
|
||||
let f3 = Fq::from_str(
|
||||
"22704845471524346880579660022678666462201713488283356385810726260959369106033",
|
||||
)
|
||||
.unwrap();
|
||||
let f4 = Fq::from_str(
|
||||
"18897508522635316277030308074760673440128491438505204942623624791502972539393",
|
||||
)
|
||||
.unwrap();
|
||||
assert!(!f1.is_zero());
|
||||
assert!(!f2.is_zero());
|
||||
assert!(!f3.is_zero());
|
||||
assert_eq!(f1 * &f2 * &f3, f4);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq_div() {
|
||||
let f1 = Fq::from_str(
|
||||
"31892744363926593013886463524057935370302352424137349660481695792871889573091",
|
||||
)
|
||||
.unwrap();
|
||||
let f2 = Fq::from_str(
|
||||
"47695868328933459965610498875668250916462767196500056002116961816137113470902",
|
||||
)
|
||||
.unwrap();
|
||||
let f3 = Fq::from_str(
|
||||
"29049672724678710659792141917402891276693777283079976086581207190825261000580",
|
||||
)
|
||||
.unwrap();
|
||||
assert!(!f1.is_zero());
|
||||
assert!(!f2.is_zero());
|
||||
assert!(!f3.is_zero());
|
||||
assert_eq!(f1 / &f2, f3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq_sub() {
|
||||
let f1 = Fq::from_str(
|
||||
"18695869713129401390241150743745601908470616448391638969502807001833388904079",
|
||||
)
|
||||
.unwrap();
|
||||
let f2 = Fq::from_str(
|
||||
"10105476028534616828778879109836101003805485072436929139123765141153277007373",
|
||||
)
|
||||
.unwrap();
|
||||
let f3 = Fq::from_str(
|
||||
"8590393684594784561462271633909500904665131375954709830379041860680111896706",
|
||||
)
|
||||
.unwrap();
|
||||
assert!(!f1.is_zero());
|
||||
assert!(!f2.is_zero());
|
||||
assert!(!f3.is_zero());
|
||||
assert_eq!(f1 - &f2, f3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq_double_in_place() {
|
||||
let mut f1 = Fq::from_str(
|
||||
"29729289787452206300641229002276778748586801323231253291984198106063944136114",
|
||||
)
|
||||
.unwrap();
|
||||
let f3 = Fq::from_str(
|
||||
"7022704399778222121834717496367591659483050145934868761364737512189307087715",
|
||||
)
|
||||
.unwrap();
|
||||
assert!(!f1.is_zero());
|
||||
assert!(!f3.is_zero());
|
||||
f1.double_in_place();
|
||||
assert_eq!(f1, f3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq_double_in_place_thrice() {
|
||||
let mut f1 = Fq::from_str(
|
||||
"32768907806651393940832831055386272949401004221411141755415956893066040832473",
|
||||
)
|
||||
.unwrap();
|
||||
let f3 = Fq::from_str(
|
||||
"52407761752706389608871686410346320244445823769178582752913020344774001921732",
|
||||
)
|
||||
.unwrap();
|
||||
assert!(!f1.is_zero());
|
||||
assert!(!f3.is_zero());
|
||||
f1.double_in_place();
|
||||
f1.double_in_place();
|
||||
f1.double_in_place();
|
||||
assert_eq!(f1, f3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq_generate_random_ed_on_bls12_381_point() {
|
||||
let d = Fq::from_str(
|
||||
"19257038036680949359750312669786877991949435402254120286184196891950884077233",
|
||||
)
|
||||
.unwrap();
|
||||
let y = Fq::from_str(
|
||||
"20269054604167148422407276086932743904275456233139568486008667107872965128512",
|
||||
)
|
||||
.unwrap();
|
||||
let x2 = Fq::from_str(
|
||||
"35041048504708632193693740149219726446678304552734087046982753200179718192840",
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let computed_y2 = y.square();
|
||||
let y2 = Fq::from_str(
|
||||
"22730681238307918419349440108285755984465605552827817317611903495170775437833",
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(y2, computed_y2);
|
||||
|
||||
let computed_dy2 = d * &computed_y2;
|
||||
let dy2 = Fq::from_str(
|
||||
"24720347560552809545835752815204882739669031262711919770503096707526812943411",
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(dy2, computed_dy2);
|
||||
|
||||
let computed_divisor = computed_dy2 + &Fq::one();
|
||||
let divisor = Fq::from_str(
|
||||
"24720347560552809545835752815204882739669031262711919770503096707526812943412",
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(divisor, computed_divisor);
|
||||
|
||||
let computed_x2 = (computed_y2 - &Fq::one()) / &computed_divisor;
|
||||
assert_eq!(x2, computed_x2);
|
||||
|
||||
let x = Fq::from_str(
|
||||
"15337652609730546173818014678723269532482775720866471265774032070871608223361",
|
||||
)
|
||||
.unwrap();
|
||||
let computed_x = computed_x2.sqrt().unwrap();
|
||||
assert_eq!(computed_x.square(), x2);
|
||||
assert_eq!(x, computed_x);
|
||||
|
||||
fn add<'a>(curr: (Fq, Fq), other: &'a (Fq, Fq)) -> (Fq, Fq) {
|
||||
let y1y2 = curr.1 * &other.1;
|
||||
let x1x2 = curr.0 * &other.0;
|
||||
let d = Fq::from_str(
|
||||
"19257038036680949359750312669786877991949435402254120286184196891950884077233",
|
||||
)
|
||||
.unwrap();
|
||||
let dx1x2y1y2 = d * &y1y2 * &x1x2;
|
||||
|
||||
let d1 = Fq::one() + &dx1x2y1y2;
|
||||
let d2 = Fq::one() - &dx1x2y1y2;
|
||||
|
||||
let x1y2 = curr.0 * &other.1;
|
||||
let y1x2 = curr.1 * &other.0;
|
||||
|
||||
let x = (x1y2 + &y1x2) / &d1;
|
||||
let y = (y1y2 + &x1x2) / &d2;
|
||||
|
||||
(x, y)
|
||||
}
|
||||
|
||||
let result = add((x, y), &(x, y));
|
||||
let result = add(result, &result);
|
||||
let result = add(result, &result);
|
||||
|
||||
let point_x = Fq::from_str(
|
||||
"47259664076168047050113154262636619161204477920503059672059915868534495873964",
|
||||
)
|
||||
.unwrap();
|
||||
let point_y = Fq::from_str(
|
||||
"19016409245280491801573912449420132838852726543024859389273314249842195919690",
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!((point_x, point_y), result);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq_square_in_place() {
|
||||
let mut f1 = Fq::from_str(
|
||||
"34864651240005695523200639428464570946052769938774601449735727714436878540682",
|
||||
)
|
||||
.unwrap();
|
||||
let f3 =
|
||||
Fq::from_str("213133100629336594719108316042277780359104840987226496279264105585804377948")
|
||||
.unwrap();
|
||||
assert!(!f1.is_zero());
|
||||
assert!(!f3.is_zero());
|
||||
f1.square_in_place();
|
||||
assert_eq!(f1, f3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq_sqrt() {
|
||||
let f1 = Fq::from_str(
|
||||
"10875927553327821418567659853801220899541454800710193788767706167237535308235",
|
||||
)
|
||||
.unwrap();
|
||||
let f3 = Fq::from_str(
|
||||
"10816221372957505053219354782681292880545918527618367765651802809826238616708",
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(f1.sqrt().unwrap(), f3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq_from_str() {
|
||||
let f1_from_repr = Fq::from(BigInteger([
|
||||
0xab8a2535947d1a77,
|
||||
0x9ba74cbfda0bbcda,
|
||||
0xe928b59724d60baf,
|
||||
0x1cccaaeb9bb1680a,
|
||||
]));
|
||||
let f1 = Fq::from_str(
|
||||
"13026376210409056429264774981357153555336288129100724591327877625017068755575",
|
||||
)
|
||||
.unwrap();
|
||||
let f2_from_repr = Fq::from(BigInteger([
|
||||
0x97e9103775d2f35c,
|
||||
0xbe6756b6c587544b,
|
||||
0x6ee38c3afd88ef4b,
|
||||
0x2bacd150f540c677,
|
||||
]));
|
||||
let f2 = Fq::from_str(
|
||||
"19754794831832707859764530223239420866832328728734160755396495950822165902172",
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(f1_from_repr, f1);
|
||||
assert_eq!(f2_from_repr, f2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq_legendre() {
|
||||
assert_eq!(QuadraticResidue, Fq::one().legendre());
|
||||
assert_eq!(Zero, Fq::zero().legendre());
|
||||
|
||||
let e = BigInteger([
|
||||
0x0dbc5349cd5664da,
|
||||
0x8ac5b6296e3ae29d,
|
||||
0x127cb819feceaa3b,
|
||||
0x3a6b21fb03867191,
|
||||
]);
|
||||
assert_eq!(QuadraticResidue, Fq::from(e).legendre());
|
||||
let e = BigInteger([
|
||||
0x96341aefd047c045,
|
||||
0x9b5f4254500a4d65,
|
||||
0x1ee08223b68ac240,
|
||||
0x31d9cd545c0ec7c6,
|
||||
]);
|
||||
assert_eq!(QuadraticNonResidue, Fq::from(e).legendre());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq_bytes() {
|
||||
let f1_from_repr = Fq::from(BigInteger([
|
||||
0xab8a2535947d1a77,
|
||||
0x9ba74cbfda0bbcda,
|
||||
0xe928b59724d60baf,
|
||||
0x1cccaaeb9bb1680a,
|
||||
]));
|
||||
|
||||
let mut f1_bytes = [0u8; 32];
|
||||
f1_from_repr.write(f1_bytes.as_mut()).unwrap();
|
||||
|
||||
let f1 = Fq::read(f1_bytes.as_ref()).unwrap();
|
||||
assert_eq!(f1_from_repr, f1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fr_add() {
|
||||
let f1 = Fr::from(BigInteger([
|
||||
0xc81265fb4130fe0c,
|
||||
0xb308836c14e22279,
|
||||
0x699e887f96bff372,
|
||||
0x84ecc7e76c11ad,
|
||||
]));
|
||||
let f2 = Fr::from(BigInteger([
|
||||
0x71875719b422efb8,
|
||||
0x0043658e68a93612,
|
||||
0x9fa756be2011e833,
|
||||
0xaa2b2cb08dac497,
|
||||
]));
|
||||
let f3 = Fr::from(BigInteger([
|
||||
0x3999bd14f553edc4,
|
||||
0xb34be8fa7d8b588c,
|
||||
0x0945df3db6d1dba5,
|
||||
0xb279f92f046d645,
|
||||
]));
|
||||
assert_eq!(f1 + &f2, f3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fr_mul() {
|
||||
let f1 = Fr::from(BigInteger([
|
||||
0xc81265fb4130fe0c,
|
||||
0xb308836c14e22279,
|
||||
0x699e887f96bff372,
|
||||
0x84ecc7e76c11ad,
|
||||
]));
|
||||
let f2 = Fr::from(BigInteger([
|
||||
0x71875719b422efb8,
|
||||
0x43658e68a93612,
|
||||
0x9fa756be2011e833,
|
||||
0xaa2b2cb08dac497,
|
||||
]));
|
||||
let f3 = Fr::from(BigInteger([
|
||||
0xbe3e50c164fe3381,
|
||||
0x5ac45bc180974585,
|
||||
0x1c234ad6dcdc70c9,
|
||||
0x15a75fba99bc8ad,
|
||||
]));
|
||||
assert_eq!(f1 * &f2, f3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fr_bytes() {
|
||||
let f1_from_repr = Fr::from(BigInteger([
|
||||
0xc81265fb4130fe0c,
|
||||
0xb308836c14e22279,
|
||||
0x699e887f96bff372,
|
||||
0x84ecc7e76c11ad,
|
||||
]));
|
||||
|
||||
let mut f1_bytes = [0u8; 32];
|
||||
f1_from_repr.write(f1_bytes.as_mut()).unwrap();
|
||||
|
||||
let f1 = Fr::read(f1_bytes.as_ref()).unwrap();
|
||||
assert_eq!(f1_from_repr, f1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fr_from_str() {
|
||||
let f100_from_repr = Fr::from(BigInteger([0x64, 0, 0, 0]));
|
||||
let f100 = Fr::from_str("100").unwrap();
|
||||
assert_eq!(f100_from_repr, f100);
|
||||
}
|
||||
37
ed_on_bls12_381_bandersnatch/src/lib.rs
Normal file
37
ed_on_bls12_381_bandersnatch/src/lib.rs
Normal file
@@ -0,0 +1,37 @@
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
#![deny(
|
||||
warnings,
|
||||
unused,
|
||||
future_incompatible,
|
||||
nonstandard_style,
|
||||
rust_2018_idioms
|
||||
)]
|
||||
#![forbid(unsafe_code)]
|
||||
|
||||
//! This library implements the Bendersnatch curve, a twisted Edwards curve
|
||||
//! whose base field is the scalar field of the curve BLS12-381. This allows
|
||||
//! defining cryptographic primitives that use elliptic curves over the scalar
|
||||
//! field of the latter curve. This curve was generated by Simon Masson from Anoma,
|
||||
//! and Antonio Sanso from Ethereum Foundation, and is also known as [bandersnatch](https://ethresear.ch/t/introducing-bandersnatch-a-fast-elliptic-curve-built-over-the-bls12-381-scalar-field/9957).
|
||||
//!
|
||||
//! See [here](https://github.com/asanso/Bandersnatch/blob/main/README.md) for the specification of the curve.
|
||||
//! There was also a Python implementation [here](https://github.com/asanso/Bandersnatch/).
|
||||
//!
|
||||
//! Curve information:
|
||||
//! * Base field: q =
|
||||
//! 52435875175126190479447740508185965837690552500527637822603658699938581184513
|
||||
//! * Scalar field: r =
|
||||
//! 13108968793781547619861935127046491459309155893440570251786403306729687672801
|
||||
//! * Valuation(q - 1, 2) = 32
|
||||
//! * Valuation(r - 1, 2) = 5
|
||||
//! * Curve equation: ax^2 + y^2 =1 + dx^2y^2, where
|
||||
//! * a = -5
|
||||
//! * d = 45022363124591815672509500913686876175488063829319466900776701791074614335719
|
||||
|
||||
#[cfg(feature = "r1cs")]
|
||||
pub mod constraints;
|
||||
mod curves;
|
||||
mod fields;
|
||||
|
||||
pub use curves::*;
|
||||
pub use fields::*;
|
||||
@@ -4,7 +4,7 @@ version = "0.3.0"
|
||||
authors = [ "arkworks contributors" ]
|
||||
description = "A Twisted Edwards curve defined over the scalar field of the BN254 curve"
|
||||
homepage = "https://arkworks.rs"
|
||||
repository = "https://github.com/arkworks-rs/algebra"
|
||||
repository = "https://github.com/arkworks-rs/curves"
|
||||
documentation = "https://docs.rs/ark-ed-on-bn254/"
|
||||
keywords = ["cryptography", "finite-fields", "elliptic-curves" ]
|
||||
categories = ["cryptography"]
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
use crate::*;
|
||||
use ark_r1cs_std::groups::curves::twisted_edwards::AffineVar;
|
||||
|
||||
use crate::constraints::FqVar;
|
||||
|
||||
/// A variable that is the R1CS equivalent of `crate::EdwardsAffine`.
|
||||
pub type EdwardsVar = AffineVar<EdwardsParameters, FqVar>;
|
||||
pub type EdwardsVar = AffineVar<EdwardsParameters>;
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
ark_curve_constraint_tests::curves::te_test::<_, EdwardsVar>().unwrap();
|
||||
ark_curve_constraint_tests::curves::te_test::<EdwardsParameters>().unwrap();
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ version = "0.3.0"
|
||||
authors = [ "arkworks contributors" ]
|
||||
description = "A Twisted Edwards curve defined over the scalar field of the BW6-761 curve"
|
||||
homepage = "https://arkworks.rs"
|
||||
repository = "https://github.com/arkworks-rs/algebra"
|
||||
repository = "https://github.com/arkworks-rs/curves"
|
||||
documentation = "https://docs.rs/ark-ed-on-bw6-761/"
|
||||
keywords = ["cryptography", "finite-fields", "elliptic-curves" ]
|
||||
categories = ["cryptography"]
|
||||
|
||||
@@ -4,7 +4,7 @@ version = "0.3.0"
|
||||
authors = [ "arkworks contributors" ]
|
||||
description = "A Twisted Edwards curve defined over the scalar field of the CP6-782 curve"
|
||||
homepage = "https://arkworks.rs"
|
||||
repository = "https://github.com/arkworks-rs/algebra"
|
||||
repository = "https://github.com/arkworks-rs/curves"
|
||||
documentation = "https://docs.rs/ark-ed-on-cp6-782/"
|
||||
keywords = ["cryptography", "finite-fields", "elliptic-curves" ]
|
||||
categories = ["cryptography"]
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
use crate::*;
|
||||
use ark_r1cs_std::groups::curves::twisted_edwards::AffineVar;
|
||||
|
||||
use crate::constraints::FqVar;
|
||||
|
||||
/// A variable that is the R1CS equivalent of `crate::EdwardsAffine`.
|
||||
pub type EdwardsVar = AffineVar<EdwardsParameters, FqVar>;
|
||||
pub type EdwardsVar = AffineVar<EdwardsParameters>;
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
ark_curve_constraint_tests::curves::te_test::<EdwardsParameters, EdwardsVar>().unwrap();
|
||||
ark_curve_constraint_tests::curves::te_test::<EdwardsParameters>().unwrap();
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ version = "0.3.0"
|
||||
authors = [ "arkworks contributors" ]
|
||||
description = "A Twisted Edwards curve defined over the scalar field of the MNT4-298 curve"
|
||||
homepage = "https://arkworks.rs"
|
||||
repository = "https://github.com/arkworks-rs/algebra"
|
||||
repository = "https://github.com/arkworks-rs/curves"
|
||||
documentation = "https://docs.rs/ark-ed-on-mnt4-298/"
|
||||
keywords = ["cryptography", "finite-fields", "elliptic-curves" ]
|
||||
categories = ["cryptography"]
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
use crate::*;
|
||||
use ark_r1cs_std::groups::curves::twisted_edwards::AffineVar;
|
||||
|
||||
use crate::constraints::fields::FqVar;
|
||||
|
||||
/// A variable that is the R1CS equivalent of `crate::EdwardsAffine`.
|
||||
pub type EdwardsVar = AffineVar<EdwardsParameters, FqVar>;
|
||||
pub type EdwardsVar = AffineVar<EdwardsParameters>;
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
ark_curve_constraint_tests::curves::te_test::<EdwardsParameters, EdwardsVar>().unwrap();
|
||||
ark_curve_constraint_tests::curves::te_test::<EdwardsParameters>().unwrap();
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ version = "0.3.0"
|
||||
authors = [ "arkworks contributors" ]
|
||||
description = "A Twisted Edwards curve defined over the scalar field of the MNT4-753 curve"
|
||||
homepage = "https://arkworks.rs"
|
||||
repository = "https://github.com/arkworks-rs/algebra"
|
||||
repository = "https://github.com/arkworks-rs/curves"
|
||||
documentation = "https://docs.rs/ark-ed-on-mnt4-753/"
|
||||
keywords = ["cryptography", "finite-fields", "elliptic-curves" ]
|
||||
categories = ["cryptography"]
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
use crate::*;
|
||||
use ark_r1cs_std::groups::curves::twisted_edwards::AffineVar;
|
||||
|
||||
use crate::constraints::fields::FqVar;
|
||||
|
||||
/// A variable that is the R1CS equivalent of `crate::EdwardsAffine`.
|
||||
pub type EdwardsVar = AffineVar<EdwardsParameters, FqVar>;
|
||||
pub type EdwardsVar = AffineVar<EdwardsParameters>;
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
ark_curve_constraint_tests::curves::te_test::<EdwardsParameters, EdwardsVar>().unwrap();
|
||||
ark_curve_constraint_tests::curves::te_test::<EdwardsParameters>().unwrap();
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ version = "0.3.0"
|
||||
authors = [ "arkworks contributors" ]
|
||||
description = "The MNT4-298 pairing-friendly elliptic curve"
|
||||
homepage = "https://arkworks.rs"
|
||||
repository = "https://github.com/arkworks-rs/algebra"
|
||||
repository = "https://github.com/arkworks-rs/curves"
|
||||
documentation = "https://docs.rs/ark-mnt4-298/"
|
||||
keywords = ["cryptography", "finite-fields" ]
|
||||
categories = ["cryptography"]
|
||||
|
||||
@@ -16,14 +16,8 @@ pub type G2PreparedVar = mnt4::G2PreparedVar<Parameters>;
|
||||
#[test]
|
||||
fn test() {
|
||||
use ark_ec::models::mnt4::MNT4Parameters;
|
||||
ark_curve_constraint_tests::curves::sw_test::<
|
||||
<Parameters as MNT4Parameters>::G1Parameters,
|
||||
G1Var,
|
||||
>()
|
||||
ark_curve_constraint_tests::curves::sw_test::<<Parameters as MNT4Parameters>::G1Parameters>()
|
||||
.unwrap();
|
||||
ark_curve_constraint_tests::curves::sw_test::<
|
||||
<Parameters as MNT4Parameters>::G2Parameters,
|
||||
G2Var,
|
||||
>()
|
||||
ark_curve_constraint_tests::curves::sw_test::<<Parameters as MNT4Parameters>::G2Parameters>()
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
@@ -130,17 +130,17 @@
|
||||
//! let pairing_result_native = MNT4_298::pairing(a_native, b_native);
|
||||
//!
|
||||
//! // Prepare `a` and `b` for pairing.
|
||||
//! let a_prep = constraints::PairingVar::prepare_g1(&a)?;
|
||||
//! let b_prep = constraints::PairingVar::prepare_g2(&b)?;
|
||||
//! let pairing_result = constraints::PairingVar::pairing(a_prep, b_prep)?;
|
||||
//! let a_prep = MNT4_298::prepare_g1(&a)?;
|
||||
//! let b_prep = MNT4_298::prepare_g2(&b)?;
|
||||
//! let pairing_result = MNT4_298::pairing_gadget(a_prep, b_prep)?;
|
||||
//!
|
||||
//! // Check that the value of &a + &b is correct.
|
||||
//! assert_eq!(pairing_result.value()?, pairing_result_native);
|
||||
//!
|
||||
//! // Check that operations on variables and constants are equivalent.
|
||||
//! let a_prep_const = constraints::PairingVar::prepare_g1(&a_const)?;
|
||||
//! let b_prep_const = constraints::PairingVar::prepare_g2(&b_const)?;
|
||||
//! let pairing_result_const = constraints::PairingVar::pairing(a_prep_const, b_prep_const)?;
|
||||
//! let a_prep_const = MNT4_298::prepare_g1(&a_const)?;
|
||||
//! let b_prep_const = MNT4_298::prepare_g2(&b_const)?;
|
||||
//! let pairing_result_const = MNT4_298::pairing_gadget(a_prep_const, b_prep_const)?;
|
||||
//! println!("Done here 3");
|
||||
//!
|
||||
//! pairing_result.enforce_equal(&pairing_result_const)?;
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
use crate::Parameters;
|
||||
|
||||
/// Specifies the constraints for computing a pairing in the MNT4-298 bilinear group.
|
||||
pub type PairingVar = ark_r1cs_std::pairing::mnt4::PairingVar<Parameters>;
|
||||
pub use crate::MNT4_298;
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
use crate::MNT4_298;
|
||||
ark_curve_constraint_tests::pairing::bilinearity_test::<MNT4_298, PairingVar>().unwrap()
|
||||
ark_curve_constraint_tests::pairing::bilinearity_test::<MNT4_298>().unwrap()
|
||||
}
|
||||
|
||||
@@ -19,12 +19,12 @@ impl ModelParameters for Parameters {
|
||||
|
||||
impl SWModelParameters for Parameters {
|
||||
/// COEFF_A = 2
|
||||
/// Reference: https://github.com/scipr-lab/libff/blob/c927821ebe02e0a24b5e0f9170cec5e211a35f08/libff/algebra/curves/mnt/mnt4/mnt4_init.cpp#L116
|
||||
/// Reference: <https://github.com/scipr-lab/libff/blob/c927821ebe02e0a24b5e0f9170cec5e211a35f08/libff/algebra/curves/mnt/mnt4/mnt4_init.cpp#L116>
|
||||
#[rustfmt::skip]
|
||||
const COEFF_A: Fq = field_new!(Fq, "2");
|
||||
|
||||
/// COEFF_B = 423894536526684178289416011533888240029318103673896002803341544124054745019340795360841685
|
||||
/// Reference: https://github.com/scipr-lab/libff/blob/c927821ebe02e0a24b5e0f9170cec5e211a35f08/libff/algebra/curves/mnt/mnt4/mnt4_init.cpp#L117
|
||||
/// Reference: <https://github.com/scipr-lab/libff/blob/c927821ebe02e0a24b5e0f9170cec5e211a35f08/libff/algebra/curves/mnt/mnt4/mnt4_init.cpp#L117>
|
||||
#[rustfmt::skip]
|
||||
const COEFF_B: Fq = field_new!(Fq, "423894536526684178289416011533888240029318103673896002803341544124054745019340795360841685");
|
||||
|
||||
@@ -45,11 +45,11 @@ impl SWModelParameters for Parameters {
|
||||
// X = 60760244141852568949126569781626075788424196370144486719385562369396875346601926534016838,
|
||||
// Y = 363732850702582978263902770815145784459747722357071843971107674179038674942891694705904306,
|
||||
/// G1_GENERATOR_X
|
||||
/// Reference: https://github.com/scipr-lab/libff/blob/c927821ebe02e0a24b5e0f9170cec5e211a35f08/libff/algebra/curves/mnt/mnt4/mnt4_init.cpp#L137
|
||||
/// Reference: <https://github.com/scipr-lab/libff/blob/c927821ebe02e0a24b5e0f9170cec5e211a35f08/libff/algebra/curves/mnt/mnt4/mnt4_init.cpp#L137>
|
||||
#[rustfmt::skip]
|
||||
pub const G1_GENERATOR_X: Fq = field_new!(Fq, "60760244141852568949126569781626075788424196370144486719385562369396875346601926534016838");
|
||||
|
||||
/// G1_GENERATOR_Y
|
||||
/// Reference: https://github.com/scipr-lab/libff/blob/c927821ebe02e0a24b5e0f9170cec5e211a35f08/libff/algebra/curves/mnt/mnt4/mnt4_init.cpp#L138
|
||||
/// Reference: <https://github.com/scipr-lab/libff/blob/c927821ebe02e0a24b5e0f9170cec5e211a35f08/libff/algebra/curves/mnt/mnt4/mnt4_init.cpp#L138>
|
||||
#[rustfmt::skip]
|
||||
pub const G1_GENERATOR_Y: Fq = field_new!(Fq, "363732850702582978263902770815145784459747722357071843971107674179038674942891694705904306");
|
||||
|
||||
@@ -4,7 +4,7 @@ version = "0.3.0"
|
||||
authors = [ "arkworks contributors" ]
|
||||
description = "The MNT4-753 pairing-friendly elliptic curve"
|
||||
homepage = "https://arkworks.rs"
|
||||
repository = "https://github.com/arkworks-rs/algebra"
|
||||
repository = "https://github.com/arkworks-rs/curves"
|
||||
documentation = "https://docs.rs/ark-mnt4-753/"
|
||||
keywords = ["cryptography", "finite-fields" ]
|
||||
categories = ["cryptography"]
|
||||
|
||||
@@ -16,14 +16,8 @@ pub type G2PreparedVar = mnt4::G2PreparedVar<Parameters>;
|
||||
#[test]
|
||||
fn test() {
|
||||
use ark_ec::models::mnt4::MNT4Parameters;
|
||||
ark_curve_constraint_tests::curves::sw_test::<
|
||||
<Parameters as MNT4Parameters>::G1Parameters,
|
||||
G1Var,
|
||||
>()
|
||||
ark_curve_constraint_tests::curves::sw_test::<<Parameters as MNT4Parameters>::G1Parameters>()
|
||||
.unwrap();
|
||||
ark_curve_constraint_tests::curves::sw_test::<
|
||||
<Parameters as MNT4Parameters>::G2Parameters,
|
||||
G2Var,
|
||||
>()
|
||||
ark_curve_constraint_tests::curves::sw_test::<<Parameters as MNT4Parameters>::G2Parameters>()
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
@@ -130,17 +130,17 @@
|
||||
//! let pairing_result_native = MNT4_753::pairing(a_native, b_native);
|
||||
//!
|
||||
//! // Prepare `a` and `b` for pairing.
|
||||
//! let a_prep = constraints::PairingVar::prepare_g1(&a)?;
|
||||
//! let b_prep = constraints::PairingVar::prepare_g2(&b)?;
|
||||
//! let pairing_result = constraints::PairingVar::pairing(a_prep, b_prep)?;
|
||||
//! let a_prep = MNT4_753::prepare_g1(&a)?;
|
||||
//! let b_prep = MNT4_753::prepare_g2(&b)?;
|
||||
//! let pairing_result = MNT4_753::pairing_gadget(a_prep, b_prep)?;
|
||||
//!
|
||||
//! // Check that the value of &a + &b is correct.
|
||||
//! assert_eq!(pairing_result.value()?, pairing_result_native);
|
||||
//!
|
||||
//! // Check that operations on variables and constants are equivalent.
|
||||
//! let a_prep_const = constraints::PairingVar::prepare_g1(&a_const)?;
|
||||
//! let b_prep_const = constraints::PairingVar::prepare_g2(&b_const)?;
|
||||
//! let pairing_result_const = constraints::PairingVar::pairing(a_prep_const, b_prep_const)?;
|
||||
//! let a_prep_const = MNT4_753::prepare_g1(&a_const)?;
|
||||
//! let b_prep_const = MNT4_753::prepare_g2(&b_const)?;
|
||||
//! let pairing_result_const = MNT4_753::pairing_gadget(a_prep_const, b_prep_const)?;
|
||||
//! println!("Done here 3");
|
||||
//!
|
||||
//! pairing_result.enforce_equal(&pairing_result_const)?;
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
use crate::Parameters;
|
||||
|
||||
/// Specifies the constraints for computing a pairing in the MNT4-753 bilinear group.
|
||||
pub type PairingVar = ark_r1cs_std::pairing::mnt4::PairingVar<Parameters>;
|
||||
pub use crate::MNT4_753;
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
use crate::MNT4_753;
|
||||
ark_curve_constraint_tests::pairing::bilinearity_test::<MNT4_753, PairingVar>().unwrap()
|
||||
ark_curve_constraint_tests::pairing::bilinearity_test::<MNT4_753>().unwrap()
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ version = "0.3.0"
|
||||
authors = [ "arkworks contributors" ]
|
||||
description = "The MNT6-298 pairing-friendly elliptic curve"
|
||||
homepage = "https://arkworks.rs"
|
||||
repository = "https://github.com/arkworks-rs/algebra"
|
||||
repository = "https://github.com/arkworks-rs/curves"
|
||||
documentation = "https://docs.rs/ark-mnt6-298/"
|
||||
keywords = ["cryptography", "finite-fields", "elliptic-curves"]
|
||||
categories = ["cryptography"]
|
||||
|
||||
@@ -16,14 +16,8 @@ pub type G2PreparedVar = mnt6::G2PreparedVar<Parameters>;
|
||||
#[test]
|
||||
fn test() {
|
||||
use ark_ec::models::mnt6::MNT6Parameters;
|
||||
ark_curve_constraint_tests::curves::sw_test::<
|
||||
<Parameters as MNT6Parameters>::G1Parameters,
|
||||
G1Var,
|
||||
>()
|
||||
ark_curve_constraint_tests::curves::sw_test::<<Parameters as MNT6Parameters>::G1Parameters>()
|
||||
.unwrap();
|
||||
ark_curve_constraint_tests::curves::sw_test::<
|
||||
<Parameters as MNT6Parameters>::G2Parameters,
|
||||
G2Var,
|
||||
>()
|
||||
ark_curve_constraint_tests::curves::sw_test::<<Parameters as MNT6Parameters>::G2Parameters>()
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
@@ -130,17 +130,17 @@
|
||||
//! let pairing_result_native = MNT6_298::pairing(a_native, b_native);
|
||||
//!
|
||||
//! // Prepare `a` and `b` for pairing.
|
||||
//! let a_prep = constraints::PairingVar::prepare_g1(&a)?;
|
||||
//! let b_prep = constraints::PairingVar::prepare_g2(&b)?;
|
||||
//! let pairing_result = constraints::PairingVar::pairing(a_prep, b_prep)?;
|
||||
//! let a_prep = MNT6_298::prepare_g1(&a)?;
|
||||
//! let b_prep = MNT6_298::prepare_g2(&b)?;
|
||||
//! let pairing_result = MNT6_298::pairing_gadget(a_prep, b_prep)?;
|
||||
//!
|
||||
//! // Check that the value of &a + &b is correct.
|
||||
//! assert_eq!(pairing_result.value()?, pairing_result_native);
|
||||
//!
|
||||
//! // Check that operations on variables and constants are equivalent.
|
||||
//! let a_prep_const = constraints::PairingVar::prepare_g1(&a_const)?;
|
||||
//! let b_prep_const = constraints::PairingVar::prepare_g2(&b_const)?;
|
||||
//! let pairing_result_const = constraints::PairingVar::pairing(a_prep_const, b_prep_const)?;
|
||||
//! let a_prep_const = MNT6_298::prepare_g1(&a_const)?;
|
||||
//! let b_prep_const = MNT6_298::prepare_g2(&b_const)?;
|
||||
//! let pairing_result_const = MNT6_298::pairing_gadget(a_prep_const, b_prep_const)?;
|
||||
//! println!("Done here 3");
|
||||
//!
|
||||
//! pairing_result.enforce_equal(&pairing_result_const)?;
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
use crate::Parameters;
|
||||
|
||||
/// Specifies the constraints for computing a pairing in the MNT6-298 bilinear group.
|
||||
pub type PairingVar = ark_r1cs_std::pairing::mnt6::PairingVar<Parameters>;
|
||||
pub use crate::MNT6_298;
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
use crate::MNT6_298;
|
||||
ark_curve_constraint_tests::pairing::bilinearity_test::<MNT6_298, PairingVar>().unwrap()
|
||||
ark_curve_constraint_tests::pairing::bilinearity_test::<MNT6_298>().unwrap()
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ version = "0.3.0"
|
||||
authors = [ "arkworks contributors" ]
|
||||
description = "The MNT6-753 pairing-friendly elliptic curve"
|
||||
homepage = "https://arkworks.rs"
|
||||
repository = "https://github.com/arkworks-rs/algebra"
|
||||
repository = "https://github.com/arkworks-rs/curves"
|
||||
documentation = "https://docs.rs/ark-mnt6-753/"
|
||||
keywords = ["cryptography", "finite-fields", "elliptic-curves" ]
|
||||
categories = ["cryptography"]
|
||||
|
||||
@@ -16,14 +16,8 @@ pub type G2PreparedVar = mnt6::G2PreparedVar<Parameters>;
|
||||
#[test]
|
||||
fn test() {
|
||||
use ark_ec::models::mnt6::MNT6Parameters;
|
||||
ark_curve_constraint_tests::curves::sw_test::<
|
||||
<Parameters as MNT6Parameters>::G1Parameters,
|
||||
G1Var,
|
||||
>()
|
||||
ark_curve_constraint_tests::curves::sw_test::<<Parameters as MNT6Parameters>::G1Parameters>()
|
||||
.unwrap();
|
||||
ark_curve_constraint_tests::curves::sw_test::<
|
||||
<Parameters as MNT6Parameters>::G2Parameters,
|
||||
G2Var,
|
||||
>()
|
||||
ark_curve_constraint_tests::curves::sw_test::<<Parameters as MNT6Parameters>::G2Parameters>()
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
@@ -130,17 +130,17 @@
|
||||
//! let pairing_result_native = MNT6_753::pairing(a_native, b_native);
|
||||
//!
|
||||
//! // Prepare `a` and `b` for pairing.
|
||||
//! let a_prep = constraints::PairingVar::prepare_g1(&a)?;
|
||||
//! let b_prep = constraints::PairingVar::prepare_g2(&b)?;
|
||||
//! let pairing_result = constraints::PairingVar::pairing(a_prep, b_prep)?;
|
||||
//! let a_prep = MNT6_753::prepare_g1(&a)?;
|
||||
//! let b_prep = MNT6_753::prepare_g2(&b)?;
|
||||
//! let pairing_result = MNT6_753::pairing_gadget(a_prep, b_prep)?;
|
||||
//!
|
||||
//! // Check that the value of &a + &b is correct.
|
||||
//! assert_eq!(pairing_result.value()?, pairing_result_native);
|
||||
//!
|
||||
//! // Check that operations on variables and constants are equivalent.
|
||||
//! let a_prep_const = constraints::PairingVar::prepare_g1(&a_const)?;
|
||||
//! let b_prep_const = constraints::PairingVar::prepare_g2(&b_const)?;
|
||||
//! let pairing_result_const = constraints::PairingVar::pairing(a_prep_const, b_prep_const)?;
|
||||
//! let a_prep_const = MNT6_753::prepare_g1(&a_const)?;
|
||||
//! let b_prep_const = MNT6_753::prepare_g2(&b_const)?;
|
||||
//! let pairing_result_const = MNT6_753::pairing_gadget(a_prep_const, b_prep_const)?;
|
||||
//! println!("Done here 3");
|
||||
//!
|
||||
//! pairing_result.enforce_equal(&pairing_result_const)?;
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
use crate::Parameters;
|
||||
|
||||
/// Specifies the constraints for computing a pairing in the MNT6-753 bilinear group.
|
||||
pub type PairingVar = ark_r1cs_std::pairing::mnt6::PairingVar<Parameters>;
|
||||
pub use crate::MNT6_753;
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
use crate::MNT6_753;
|
||||
ark_curve_constraint_tests::pairing::bilinearity_test::<MNT6_753, PairingVar>().unwrap()
|
||||
ark_curve_constraint_tests::pairing::bilinearity_test::<MNT6_753>().unwrap()
|
||||
}
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
use crate::*;
|
||||
use ark_r1cs_std::groups::curves::short_weierstrass::ProjectiveVar;
|
||||
|
||||
use crate::constraints::FBaseVar;
|
||||
|
||||
/// A group element in the Pallas prime-order group.
|
||||
pub type GVar = ProjectiveVar<PallasParameters, FBaseVar>;
|
||||
pub type GVar = ProjectiveVar<PallasParameters>;
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
ark_curve_constraint_tests::curves::sw_test::<PallasParameters, GVar>().unwrap();
|
||||
ark_curve_constraint_tests::curves::sw_test::<PallasParameters>().unwrap();
|
||||
}
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
use crate::*;
|
||||
use ark_r1cs_std::groups::curves::short_weierstrass::ProjectiveVar;
|
||||
|
||||
use crate::constraints::FBaseVar;
|
||||
|
||||
/// A group element in the Vesta prime-order group.
|
||||
pub type GVar = ProjectiveVar<VestaParameters, FBaseVar>;
|
||||
pub type GVar = ProjectiveVar<VestaParameters>;
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
ark_curve_constraint_tests::curves::sw_test::<VestaParameters, GVar>().unwrap();
|
||||
ark_curve_constraint_tests::curves::sw_test::<VestaParameters>().unwrap();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user