Merge pull request #84 from zcash/pasta-curves

Replace Tweedle curves with Pasta curves
This commit is contained in:
ebfull 2020-12-13 08:51:52 -07:00 committed by GitHub
commit 7c0e56a44e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 319 additions and 195 deletions

View File

@ -3,9 +3,9 @@ extern crate criterion;
extern crate halo2;
use crate::arithmetic::{small_multiexp, FieldExt};
use crate::pasta::{EqAffine, Fp, Fq};
use crate::poly::commitment::Params;
use crate::transcript::DummyHash;
use crate::tweedle::{EqAffine, Fp, Fq};
use halo2::*;
use criterion::{black_box, Criterion};

View File

@ -3,10 +3,10 @@ extern crate criterion;
extern crate halo2;
use halo2::arithmetic::FieldExt;
use halo2::pasta::{EqAffine, Fp, Fq};
use halo2::plonk::*;
use halo2::poly::commitment::Params;
use halo2::transcript::DummyHash;
use halo2::tweedle::{EqAffine, Fp, Fq};
use std::marker::PhantomData;

View File

@ -1,10 +1,10 @@
use halo2::{
arithmetic::{Curve, FieldExt},
model::ModelRecorder,
pasta::{EqAffine, Fp, Fq},
plonk::*,
poly::commitment::{Blind, Params},
transcript::DummyHash,
tweedle::{EqAffine, Fp, Fq},
};
use std::marker::PhantomData;

View File

@ -468,7 +468,7 @@ pub fn lagrange_interpolate<F: FieldExt>(points: &[F], evals: &[F]) -> Vec<F> {
}
#[cfg(test)]
use crate::tweedle::Fp;
use crate::pasta::Fp;
#[test]
fn test_lagrange_interpolate() {

View File

@ -14,9 +14,9 @@
#![deny(unsafe_code)]
pub mod arithmetic;
pub mod pasta;
pub mod plonk;
pub mod poly;
pub mod transcript;
pub mod tweedle;
pub mod model;

23
src/pasta.rs Normal file
View File

@ -0,0 +1,23 @@
//! This module contains implementations for the Pallas and Vesta elliptic curve
//! groups.
#[macro_use]
mod macros;
mod curves;
mod fields;
pub mod pallas;
pub mod vesta;
pub use curves::*;
pub use fields::*;
#[test]
fn test_endo_consistency() {
use crate::arithmetic::{Curve, FieldExt};
let a = pallas::Point::one();
assert_eq!(a * pallas::Scalar::ZETA, a.endo());
let a = vesta::Point::one();
assert_eq!(a * vesta::Scalar::ZETA, a.endo());
}

View File

@ -1,5 +1,5 @@
//! This module contains implementations for the Tweedledum and Tweedledee
//! elliptic curve groups.
//! This module contains implementations for the Pallas and Vesta elliptic curve
//! groups.
use core::cmp;
use core::fmt::Debug;

View File

@ -1,5 +1,5 @@
//! This module contains implementations for the two finite fields of the
//! Tweedledum and Tweedledee curves.
//! This module contains implementations for the two finite fields of the Pallas
//! and Vesta curves.
mod fp;
mod fq;

View File

@ -9,9 +9,9 @@ use crate::arithmetic::{adc, mac, sbb, FieldExt, Group};
/// This represents an element of $\mathbb{F}_p$ where
///
/// `p = 0x40000000000000000000000000000000038aa1276c3f59b9a14064e200000001`
/// `p = 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001`
///
/// is the base field of the Tweedledum curve.
/// is the base field of the Pallas curve.
// The internal representation of this type is four 64-bit unsigned
// integers in little-endian order. `Fp` values are always in
// Montgomery form; i.e., Fp(a) = aR mod p, with R = 2^256.
@ -94,11 +94,11 @@ impl ConditionallySelectable for Fp {
}
/// Constant representing the modulus
/// p = 0x40000000000000000000000000000000038aa1276c3f59b9a14064e200000001
/// p = 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001
const MODULUS: Fp = Fp([
0xa14064e200000001,
0x38aa1276c3f59b9,
0x0,
0x992d30ed00000001,
0x224698fc094cf91b,
0x0000000000000000,
0x4000000000000000,
]);
@ -106,9 +106,9 @@ const MODULUS: Fp = Fp([
#[cfg(not(target_pointer_width = "64"))]
const MODULUS_LIMBS_32: [u32; 8] = [
0x0000_0001,
0xa140_64e2,
0x6c3f_59b9,
0x038a_a127,
0x992d_30ed,
0x094c_f91b,
0x2246_98fc,
0x0000_0000,
0x0000_0000,
0x0000_0000,
@ -164,34 +164,34 @@ impl_binops_additive!(Fp, Fp);
impl_binops_multiplicative!(Fp, Fp);
/// INV = -(p^{-1} mod 2^64) mod 2^64
const INV: u64 = 0xa14064e1ffffffff;
const INV: u64 = 0x992d30ecffffffff;
/// R = 2^256 mod p
const R: Fp = Fp([
0x1c3ed159fffffffd,
0xf5601c89bb41f2d3,
0x34786d38fffffffd,
0x992c350be41914ad,
0xffffffffffffffff,
0x3fffffffffffffff,
]);
/// R^2 = 2^512 mod p
const R2: Fp = Fp([
0x280c9c4000000010,
0x91a4409b5400af74,
0xdd7b28e19094c659,
0xc8ad9107ccca0e,
0x8c78ecb30000000f,
0xd7d30dbd8b0de0e7,
0x7797a99bc3c95d18,
0x096d41af7b9cb714,
]);
/// R^3 = 2^768 mod p
const R3: Fp = Fp([
0x98fb3d144380a737,
0xf9fdbeb55b7eb87c,
0x63f75cb999eafa89,
0x217cb214ebb8fc72,
0xf185a5993a9e10f9,
0xf6a68f3b6ac5b1d1,
0xdf8d1014353fd42c,
0x2ae309222d2d9910,
]);
/// `GENERATOR = 5 mod p` is a generator of the `p - 1` order multiplicative subgroup, and
/// is also a quadratic non-residue.
/// `GENERATOR = 5 mod p` is a generator of the `p - 1` order multiplicative
/// subgroup, or in other words a primitive root of the field.
const GENERATOR: Fp = Fp::from_raw([
0x0000_0000_0000_0005,
0x0000_0000_0000_0000,
@ -199,34 +199,26 @@ const GENERATOR: Fp = Fp::from_raw([
0x0000_0000_0000_0000,
]);
const S: u32 = 33;
const S: u32 = 32;
/// GENERATOR^t where t * 2^s + 1 = p
/// with t odd. In other words, this
/// is a 2^s root of unity.
///
/// `GENERATOR = 5 mod p` is a generator
/// of the p - 1 order multiplicative
/// subgroup.
const ROOT_OF_UNITY: Fp = Fp::from_raw([
0x53de9f31b88837ce,
0xff46e8f3f3ea99d6,
0xf624f2eaaf8c2d57,
0x2ae45117890ee2fc,
0xbdad6fabd87ea32f,
0xea322bf2b7bb7584,
0x362120830561f81a,
0x2bce74deac30ebda,
]);
/// GENERATOR^{2^s} where t * 2^s + 1 = p
/// with t odd. In other words, this
/// is a t root of unity.
///
/// `GENERATOR = 5 mod p` is a generator
/// of the p - 1 order multiplicative
/// subgroup.
const DELTA: Fp = Fp::from_raw([
0x48796f6fde98a425,
0xa99d8b67e918805e,
0x671383de08b5fe3c,
0x1e9372724e80300d,
0x6a6ccd20dd7b9ba2,
0xf5e4f3f13eee5636,
0xbd455b7112a5049d,
0x0a757d0f0006ab6c,
]);
impl Default for Fp {
@ -503,7 +495,7 @@ impl ff::Field for Fp {
// https://eprint.iacr.org/2012/685.pdf (page 12, algorithm 5)
// w = self^((t - 1) // 2)
let w = self.pow_vartime(&[0xdb0fd66e68501938, 0xe2a849, 0x0, 0x10000000]);
let w = self.pow_vartime(&[0x04a67c8dcc969876, 0x11234c7e, 0x0, 0x20000000]);
let mut v = S;
let mut x = self * w;
@ -544,8 +536,8 @@ impl ff::Field for Fp {
/// failing if the element is zero.
fn invert(&self) -> CtOption<Self> {
let tmp = self.pow_vartime(&[
0xa14064e1ffffffff,
0x38aa1276c3f59b9,
0x992d30ecffffffff,
0x224698fc094cf91b,
0x0,
0x4000000000000000,
]);
@ -646,43 +638,43 @@ impl ff::PrimeField for Fp {
impl FieldExt for Fp {
const ROOT_OF_UNITY: Self = ROOT_OF_UNITY;
const ROOT_OF_UNITY_INV: Self = Fp::from_raw([
0x9246674078fa45bb,
0xd822ebd60888c5ea,
0x56d579133a11731f,
0x1c88fa9e942120bb,
0xf0b87c7db2ce91f6,
0x84a0a1d8859f066f,
0xb4ed8e647196dad1,
0x2cd5282c53116b5c,
]);
const UNROLL_T_EXPONENT: [u64; 4] = [
0x3b3a6633d1897d83,
0x0000000000c93d5b,
0xf000000000000000,
0xe34ab16,
0x955a0a417453113c,
0x0000000022016b89,
0xc000000000000000,
0x3f7ed4c6,
];
const T_EXPONENT: [u64; 4] = [
0xb61facdcd0a03271,
0x0000000001c55093,
0x094cf91b992d30ed,
0x00000000224698fc,
0x0000000000000000,
0x20000000,
0x40000000,
];
const DELTA: Self = DELTA;
const UNROLL_S_EXPONENT: u64 = 0x11cb54e91;
const UNROLL_S_EXPONENT: u64 = 0x204ace5;
const TWO_INV: Self = Fp::from_raw([
0xd0a0327100000001,
0x01c55093b61facdc,
0xcc96987680000001,
0x11234c7e04a67c8d,
0x0000000000000000,
0x2000000000000000,
]);
const RESCUE_ALPHA: u64 = 5;
const RESCUE_INVALPHA: [u64; 4] = [
0x810050b4cccccccd,
0x360880ec56991494,
0xe0f0f3f0cccccccd,
0x4e9ee0c9a10a60e2,
0x3333333333333333,
0x3333333333333333,
];
const ZETA: Self = Fp::from_raw([
0x8598abb3a410c9c8,
0x7881fb239ba41a26,
0x9bebc9146ef83d9a,
0x1508415ab5e97c94,
0x1dad5ebdfdfe4ab9,
0x1d1f8bd237ad3149,
0x2caad5dc57aab1b0,
0x12ccca834acdba71,
]);
fn ct_is_zero(&self) -> Choice {
@ -781,11 +773,36 @@ fn test_inv() {
assert_eq!(inv, INV);
}
#[test]
fn test_rescue() {
// NB: TWO_INV is standing in as a "random" field element
assert_eq!(
Fp::TWO_INV
.pow_vartime(&[Fp::RESCUE_ALPHA, 0, 0, 0])
.pow_vartime(&Fp::RESCUE_INVALPHA),
Fp::TWO_INV
);
}
#[test]
fn test_sqrt() {
// NB: TWO_INV is standing in as a "random" field element
let v = (Fp::TWO_INV).square().sqrt().unwrap();
assert!(v == Fp::TWO_INV || (-v) == Fp::TWO_INV);
}
#[test]
fn test_deterministic_sqrt() {
// NB: TWO_INV is standing in as a "random" field element
let v = (Fp::TWO_INV).square().deterministic_sqrt().unwrap();
assert!(v == Fp::TWO_INV || (-v) == Fp::TWO_INV);
}
#[test]
fn test_zeta() {
assert_eq!(
format!("{:?}", Fp::ZETA),
"0x1508415ab5e97c949bebc9146ef83d9a7881fb239ba41a268598abb3a410c9c8"
"0x12ccca834acdba712caad5dc57aab1b01d1f8bd237ad31491dad5ebdfdfe4ab9"
);
let a = Fp::ZETA;
@ -796,6 +813,14 @@ fn test_zeta() {
assert!(c == Fp::one());
}
#[test]
fn test_root_of_unity() {
assert_eq!(
Fp::ROOT_OF_UNITY.pow_vartime(&[1 << Fp::S, 0, 0, 0]),
Fp::one()
);
}
#[test]
fn test_inv_root_of_unity() {
assert_eq!(Fp::ROOT_OF_UNITY_INV, Fp::ROOT_OF_UNITY.invert().unwrap());
@ -808,5 +833,45 @@ fn test_inv_2() {
#[test]
fn test_delta() {
assert_eq!(Fp::DELTA, Fp::from(5).pow(&[1u64 << Fp::S, 0, 0, 0]));
assert_eq!(Fp::DELTA, GENERATOR.pow(&[1u64 << Fp::S, 0, 0, 0]));
assert_eq!(Fp::DELTA, Fp::multiplicative_generator().pow(&[1u64 << Fp::S, 0, 0, 0]));
}
#[cfg(not(target_pointer_width = "64"))]
#[test]
fn consistent_modulus_limbs() {
for (a, &b) in MODULUS
.0
.iter()
.flat_map(|&limb| {
Some(limb as u32)
.into_iter()
.chain(Some((limb >> 32) as u32))
})
.zip(MODULUS_LIMBS_32.iter())
{
assert_eq!(a, b);
}
}
#[test]
fn test_from_u512() {
assert_eq!(
Fp::from_raw([
0x3daec14d565241d9,
0x0b7af45b6073944b,
0xea5b8bd611a5bd4c,
0x150160330625db3d
]),
Fp::from_u512([
0xee155641297678a1,
0xd83e156bdbfdbe65,
0xd9ccd834c68ba0b5,
0xf508ede312272758,
0x038df7cbf8228e89,
0x3505a1e4a3c74b41,
0xbfa46f775eb82db3,
0x26ebe27e262f471d
])
);
}

View File

@ -9,9 +9,9 @@ use crate::arithmetic::{adc, mac, sbb, FieldExt, Group};
/// This represents an element of $\mathbb{F}_q$ where
///
/// `q = 0x40000000000000000000000000000000038aa127696286c9842cafd400000001`
/// `q = 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001`
///
/// is the base field of the Tweedledee curve.
/// is the base field of the Vesta curve.
// The internal representation of this type is four 64-bit unsigned
// integers in little-endian order. `Fq` values are always in
// Montgomery form; i.e., Fq(a) = aR mod q, with R = 2^256.
@ -94,10 +94,10 @@ impl ConditionallySelectable for Fq {
}
/// Constant representing the modulus
/// q = 0x40000000000000000000000000000000038aa127696286c9842cafd400000001
/// q = 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001
const MODULUS: Fq = Fq([
0x842cafd400000001,
0x38aa127696286c9,
0x8c46eb2100000001,
0x224698fc0994a8dd,
0x0,
0x4000000000000000,
]);
@ -106,9 +106,9 @@ const MODULUS: Fq = Fq([
#[cfg(not(target_pointer_width = "64"))]
const MODULUS_LIMBS_32: [u32; 8] = [
0x0000_0001,
0x842c_afd4,
0x6962_86c9,
0x038a_a127,
0x8c46_eb21,
0x0994_a8dd,
0x2246_98fc,
0x0000_0000,
0x0000_0000,
0x0000_0000,
@ -164,34 +164,34 @@ impl_binops_additive!(Fq, Fq);
impl_binops_multiplicative!(Fq, Fq);
/// INV = -(q^{-1} mod 2^64) mod 2^64
const INV: u64 = 0x842cafd3ffffffff;
const INV: u64 = 0x8c46eb20ffffffff;
/// R = 2^256 mod q
const R: Fq = Fq([
0x7379f083fffffffd,
0xf5601c89c3d86ba3,
0x5b2b3e9cfffffffd,
0x992c350be3420567,
0xffffffffffffffff,
0x3fffffffffffffff,
]);
/// R^2 = 2^512 mod q
const R2: Fq = Fq([
0x8595fa8000000010,
0x7e16a565c6895230,
0xf4c0e6fcb03aa0a2,
0xc8ad9106886013,
0xfc9678ff0000000f,
0x67bb433d891a16e3,
0x7fae231004ccf590,
0x096d41af7ccfdaa9,
]);
/// R^3 = 2^768 mod q
const R3: Fq = Fq([
0xa624f338075cdb5e,
0x57964eacb8fe21f2,
0xcb266d18c0413bc2,
0xa42cdf95f959577,
0x008b421c249dae4c,
0xe13bda50dba41326,
0x88fececb8e15cb63,
0x07dd97a06e6792c8,
]);
/// `GENERATOR = 5 mod q` is a generator of the `q - 1` order multiplicative subgroup, and
/// is also a quadratic non-residue.
/// `GENERATOR = 5 mod q` is a generator of the `q - 1` order multiplicative
/// subgroup, or in other words a primitive root of the field.
const GENERATOR: Fq = Fq::from_raw([
0x0000_0000_0000_0005,
0x0000_0000_0000_0000,
@ -199,34 +199,26 @@ const GENERATOR: Fq = Fq::from_raw([
0x0000_0000_0000_0000,
]);
const S: u32 = 34;
const S: u32 = 32;
/// GENERATOR^t where t * 2^s + 1 = q
/// with t odd. In other words, this
/// is a 2^s root of unity.
///
/// `GENERATOR = 5 mod q` is a generator
/// of the q - 1 order multiplicative
/// subgroup.
const ROOT_OF_UNITY: Fq = Fq::from_raw([
0x1cbd3234869d57ec,
0xa287dd1b8084fbf,
0xf1dbcb645a987293,
0x113efc510dc03c0b,
0xa70e2c1102b6d05f,
0x9bb97ea3c106f049,
0x9e5c4dfd492ae26e,
0x2de6a9b8746d3f58,
]);
/// GENERATOR^{2^s} where t * 2^s + 1 = q
/// with t odd. In other words, this
/// is a t root of unity.
///
/// `GENERATOR = 5 mod q` is a generator
/// of the q - 1 order multiplicative
/// subgroup.
const DELTA: Fq = Fq::from_raw([
0x83d2833d15f2bbf9,
0x5127e2ce24a8e69c,
0x4243423589e0a9b5,
0x20daec44973be920,
0x8494392472d1683c,
0xe3ac3376541d1140,
0x06f0a88e7f7949f8,
0x2237d54423724166,
]);
impl Default for Fq {
@ -256,21 +248,6 @@ impl Fq {
self.add(self)
}
/// Converts a 512-bit little endian integer into
/// a `Fq` by reducing by the modulus.
pub fn from_bytes_wide(bytes: &[u8; 64]) -> Fq {
Fq::from_u512([
u64::from_le_bytes(bytes[0..8].try_into().unwrap()),
u64::from_le_bytes(bytes[8..16].try_into().unwrap()),
u64::from_le_bytes(bytes[16..24].try_into().unwrap()),
u64::from_le_bytes(bytes[24..32].try_into().unwrap()),
u64::from_le_bytes(bytes[32..40].try_into().unwrap()),
u64::from_le_bytes(bytes[40..48].try_into().unwrap()),
u64::from_le_bytes(bytes[48..56].try_into().unwrap()),
u64::from_le_bytes(bytes[56..64].try_into().unwrap()),
])
}
fn from_u512(limbs: [u64; 8]) -> Fq {
// We reduce an arbitrary 512-bit number by decomposing it into two 256-bit digits
// with the higher bits multiplied by 2^256. Thus, we perform two reductions
@ -518,7 +495,7 @@ impl ff::Field for Fq {
// https://eprint.iacr.org/2012/685.pdf (page 12, algorithm 5)
// w = self^((t - 1) // 2)
let w = self.pow_vartime(&[0xed2c50d9308595fa, 0x715424, 0x0, 0x8000000]);
let w = self.pow_vartime(&[0x04ca546ec6237590, 0x11234c7e, 0x0, 0x20000000]);
let mut v = S;
let mut x = self * w;
@ -559,8 +536,8 @@ impl ff::Field for Fq {
/// failing if the element is zero.
fn invert(&self) -> CtOption<Self> {
let tmp = self.pow_vartime(&[
0x842cafd3ffffffff,
0x38aa127696286c9,
0x8c46eb20ffffffff,
0x224698fc0994a8dd,
0x0,
0x4000000000000000,
]);
@ -661,43 +638,43 @@ impl ff::PrimeField for Fq {
impl FieldExt for Fq {
const ROOT_OF_UNITY: Self = ROOT_OF_UNITY;
const ROOT_OF_UNITY_INV: Self = Fq::from_raw([
0x824860d3eb30de02,
0xad9f0afd0ea63acc,
0xd250318c11a16fe1,
0x12a9f5e1dd62dabc,
0x57eecda0a84b6836,
0x4ad38b9084b8a80c,
0xf4c8f353124086c1,
0x2235e1a7415bf936,
]);
const UNROLL_T_EXPONENT: [u64; 4] = [
0x9b71de17e6d2d5a0,
0x0000000000296ee0,
0x8c00000000000000,
0x2ecc05e,
0xcc771cc2ac1e1664,
0x00000000062dfe9e,
0xc000000000000000,
0xb89e9c7,
];
const T_EXPONENT: [u64; 4] = [
0xda58a1b2610b2bf5,
0x0000000000e2a849,
0x0994a8dd8c46eb21,
0x00000000224698fc,
0x0000000000000000,
0x10000000,
0x40000000,
];
const DELTA: Self = DELTA;
const UNROLL_S_EXPONENT: u64 = 0x344cfe85d;
const UNROLL_S_EXPONENT: u64 = 0xd1d858e1;
const TWO_INV: Self = Fq::from_raw([
0xc21657ea00000001,
0x01c55093b4b14364,
0xc623759080000001,
0x11234c7e04ca546e,
0x0000000000000000,
0x2000000000000000,
]);
const RESCUE_ALPHA: u64 = 5;
const RESCUE_INVALPHA: [u64; 4] = [
0xd023bfdccccccccd,
0x360880ec544ed23a,
0xd69f2280cccccccd,
0x4e9ee0c9a143ba4a,
0x3333333333333333,
0x3333333333333333,
];
const ZETA: Self = Fq::from_raw([
0x4394c2bd148fa4fd,
0x69cf8de720e52ec1,
0x87ad8b5ff9731ffe,
0x36c66d3a1e049a58,
0x2aa9d2e050aa0e4f,
0x0fed467d47c033af,
0x511db4d81cf70f5a,
0x06819a58283e528e,
]);
fn ct_is_zero(&self) -> Choice {
@ -796,11 +773,36 @@ fn test_inv() {
assert_eq!(inv, INV);
}
#[test]
fn test_rescue() {
// NB: TWO_INV is standing in as a "random" field element
assert_eq!(
Fq::TWO_INV
.pow_vartime(&[Fq::RESCUE_ALPHA, 0, 0, 0])
.pow_vartime(&Fq::RESCUE_INVALPHA),
Fq::TWO_INV
);
}
#[test]
fn test_sqrt() {
// NB: TWO_INV is standing in as a "random" field element
let v = (Fq::TWO_INV).square().sqrt().unwrap();
assert!(v == Fq::TWO_INV || (-v) == Fq::TWO_INV);
}
#[test]
fn test_deterministic_sqrt() {
// NB: TWO_INV is standing in as a "random" field element
let v = (Fq::TWO_INV).square().deterministic_sqrt().unwrap();
assert!(v == Fq::TWO_INV || (-v) == Fq::TWO_INV);
}
#[test]
fn test_zeta() {
assert_eq!(
format!("{:?}", Fq::ZETA),
"0x36c66d3a1e049a5887ad8b5ff9731ffe69cf8de720e52ec14394c2bd148fa4fd"
"0x06819a58283e528e511db4d81cf70f5a0fed467d47c033af2aa9d2e050aa0e4f"
);
let a = Fq::ZETA;
assert!(a != Fq::one());
@ -810,6 +812,14 @@ fn test_zeta() {
assert!(c == Fq::one());
}
#[test]
fn test_root_of_unity() {
assert_eq!(
Fq::ROOT_OF_UNITY.pow_vartime(&[1 << Fq::S, 0, 0, 0]),
Fq::one()
);
}
#[test]
fn test_inv_root_of_unity() {
assert_eq!(Fq::ROOT_OF_UNITY_INV, Fq::ROOT_OF_UNITY.invert().unwrap());
@ -822,5 +832,45 @@ fn test_inv_2() {
#[test]
fn test_delta() {
assert_eq!(Fq::DELTA, Fq::from(5).pow(&[1u64 << Fq::S, 0, 0, 0]));
assert_eq!(Fq::DELTA, GENERATOR.pow(&[1u64 << Fq::S, 0, 0, 0]));
assert_eq!(Fq::DELTA, Fq::multiplicative_generator().pow(&[1u64 << Fq::S, 0, 0, 0]));
}
#[cfg(not(target_pointer_width = "64"))]
#[test]
fn consistent_modulus_limbs() {
for (a, &b) in MODULUS
.0
.iter()
.flat_map(|&limb| {
Some(limb as u32)
.into_iter()
.chain(Some((limb >> 32) as u32))
})
.zip(MODULUS_LIMBS_32.iter())
{
assert_eq!(a, b);
}
}
#[test]
fn test_from_u512() {
assert_eq!(
Fq::from_raw([
0xe22bd0d1b22cc43e,
0x6b84e5b52490a7c8,
0x264262941ac9e229,
0x27dcfdf361ce4254
]),
Fq::from_u512([
0x64a80cce0b5a2369,
0x84f2ef0501bc783c,
0x696e5e63c86bbbde,
0x924072f52dc6cc62,
0x8288a507c8d61128,
0x3b2efb1ef697e3fe,
0x75a4998d06855f27,
0x52ea589e69712cc0
])
);
}

13
src/pasta/pallas.rs Normal file
View File

@ -0,0 +1,13 @@
//! The Pallas elliptic curve group.
/// A Pallas point in the projective coordinate space.
pub type Point = super::Ep;
/// A Pallas point in the affine coordinate space (or the point at infinity).
pub type Affine = super::EpAffine;
/// The base field of the Pallas group.
pub type Base = super::Fp;
/// The scalar field of the Pallas group.
pub type Scalar = super::Fq;

13
src/pasta/vesta.rs Normal file
View File

@ -0,0 +1,13 @@
//! The Vesta elliptic curve group.
/// A Vesta point in the projective coordinate space.
pub type Point = super::Eq;
/// A Vesta point in the affine coordinate space (or the point at infinity).
pub type Affine = super::EqAffine;
/// The base field of the Vesta group.
pub type Base = super::Fq;
/// The scalar field of the Vesta group.
pub type Scalar = super::Fp;

View File

@ -119,9 +119,9 @@ type ChallengeX<F> = ChallengeScalar<F, X>;
#[test]
fn test_proving() {
use crate::arithmetic::{Curve, FieldExt};
use crate::pasta::{EqAffine, Fp, Fq};
use crate::poly::commitment::{Blind, Params};
use crate::transcript::DummyHash;
use crate::tweedle::{EqAffine, Fp, Fq};
use circuit::{Advice, Column, Fixed};
use std::marker::PhantomData;
const K: u32 = 5;

View File

@ -103,7 +103,6 @@ impl<C: CurveAffine> Params<C> {
let h = {
let mut hasher = H::init(C::Base::zero());
hasher.absorb(-C::Base::one());
let x = hasher.squeeze().to_bytes();
let p = C::from_bytes(&x);
p.unwrap()
@ -226,8 +225,8 @@ impl<F: FieldExt> MulAssign<F> for Blind<F> {
fn test_commit_lagrange() {
const K: u32 = 6;
use crate::pasta::{EpAffine, Fp, Fq};
use crate::transcript::DummyHash;
use crate::tweedle::{EpAffine, Fp, Fq};
let params = Params::<EpAffine>::new::<DummyHash<Fp>>(K);
let domain = super::EvaluationDomain::new(1, K);
@ -255,8 +254,8 @@ fn test_opening_proof() {
EvaluationDomain,
};
use crate::arithmetic::{eval_polynomial, Curve, FieldExt};
use crate::pasta::{EpAffine, Fp, Fq};
use crate::transcript::{ChallengeScalar, DummyHash, Transcript};
use crate::tweedle::{EpAffine, Fp, Fq};
let params = Params::<EpAffine>::new::<DummyHash<Fp>>(K);
let domain = EvaluationDomain::new(1, K);

View File

@ -217,7 +217,7 @@ where
mod tests {
use super::{construct_intermediate_sets, Query};
use crate::arithmetic::FieldExt;
use crate::tweedle::Fp;
use crate::pasta::Fp;
#[derive(Clone)]
struct MyQuery<F> {

View File

@ -1,13 +0,0 @@
//! This module contains implementations for the Tweedledum and Tweedledee
//! elliptic curve groups.
#[macro_use]
mod macros;
mod curves;
mod fields;
pub mod dee;
pub mod dum;
pub use curves::*;
pub use fields::*;

View File

@ -1,13 +0,0 @@
//! The Tweedledee elliptic curve group.
/// A Tweedledee point in the projective coordinate space.
pub type Point = super::Eq;
/// A Tweedledee point in the affine coordinate space (or the point at infinity).
pub type Affine = super::EqAffine;
/// The base field of the Tweedledee group.
pub type Base = super::Fq;
/// The scalar field of the Tweedledee group.
pub type Scalar = super::Fp;

View File

@ -1,13 +0,0 @@
//! The Tweedledum elliptic curve group.
/// A Tweedledum point in the projective coordinate space.
pub type Point = super::Ep;
/// A Tweedledum point in the affine coordinate space (or the point at infinity).
pub type Affine = super::EpAffine;
/// The base field of the Tweedledum group.
pub type Base = super::Fp;
/// The scalar field of the Tweedledum group.
pub type Scalar = super::Fq;