mirror of
https://github.com/saymrwulf/pasta_curves-source.git
synced 2026-09-04 20:03:39 +00:00
Migrate to group traits
The `Curve` trait is now `CurveExt: group::prime::PrimeCurve`, and `CurveAffine` is now `CurveAffine: group::prime::PrimeCurveAffine`. There is no `CurveAffine` trait in `group`, and it's a widely-used trait in this crate, so we don't rename it to `CurveAffineExt`.
This commit is contained in:
parent
55fb581f17
commit
b4ed5295fe
24 changed files with 200 additions and 184 deletions
|
|
@ -43,6 +43,7 @@ backtrace = { version = "0.3", optional = true }
|
|||
subtle = "2.3"
|
||||
crossbeam-utils = "0.8"
|
||||
ff = "0.9"
|
||||
group = "0.9"
|
||||
metrics = "0.14.2"
|
||||
num_cpus = "1.13"
|
||||
rand = "0.8"
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
use criterion::{criterion_group, criterion_main, Criterion};
|
||||
|
||||
use halo2::arithmetic::Curve;
|
||||
use halo2::arithmetic::CurveExt;
|
||||
use halo2::pasta::{pallas, vesta};
|
||||
|
||||
fn criterion_benchmark(c: &mut Criterion) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use group::Curve;
|
||||
use halo2::{
|
||||
arithmetic::{Curve, FieldExt},
|
||||
arithmetic::FieldExt,
|
||||
model::ModelRecorder,
|
||||
pasta::{EqAffine, Fp},
|
||||
plonk::*,
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
use crossbeam_utils::thread;
|
||||
pub use ff::Field;
|
||||
use group::Group as _;
|
||||
|
||||
mod curves;
|
||||
mod fields;
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
//! write code that generalizes over a pair of groups.
|
||||
|
||||
use core::cmp;
|
||||
use core::fmt::Debug;
|
||||
use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
|
||||
use core::ops::{Add, Sub};
|
||||
use group::prime::{PrimeCurve, PrimeCurveAffine};
|
||||
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption};
|
||||
|
||||
use super::{FieldExt, Group};
|
||||
|
|
@ -13,66 +13,26 @@ use std::io::{self, Read, Write};
|
|||
/// This trait is a common interface for dealing with elements of an elliptic
|
||||
/// curve group in a "projective" form, where that arithmetic is usually more
|
||||
/// efficient.
|
||||
pub trait Curve:
|
||||
Sized
|
||||
pub trait CurveExt:
|
||||
PrimeCurve
|
||||
+ group::Group<Scalar = <Self as CurveExt>::ScalarExt>
|
||||
+ Default
|
||||
+ Copy
|
||||
+ Clone
|
||||
+ Send
|
||||
+ Sync
|
||||
+ 'static
|
||||
+ Debug
|
||||
+ Add<Output = Self>
|
||||
+ Sub<Output = Self>
|
||||
+ Mul<<Self as Curve>::Scalar, Output = Self>
|
||||
+ Neg<Output = Self>
|
||||
+ for<'a> Add<&'a Self, Output = Self>
|
||||
+ for<'a> Sub<&'a Self, Output = Self>
|
||||
+ MulAssign<<Self as Curve>::Scalar>
|
||||
+ AddAssign
|
||||
+ SubAssign
|
||||
+ for<'a> AddAssign<&'a Self>
|
||||
+ for<'a> SubAssign<&'a Self>
|
||||
+ AddAssign<<Self as Curve>::Affine>
|
||||
+ SubAssign<<Self as Curve>::Affine>
|
||||
+ PartialEq
|
||||
+ cmp::Eq
|
||||
+ ConditionallySelectable
|
||||
+ ConstantTimeEq
|
||||
+ From<<Self as Curve>::Affine>
|
||||
+ Group<Scalar = <Self as Curve>::Scalar>
|
||||
+ From<<Self as PrimeCurve>::Affine>
|
||||
+ Group<Scalar = <Self as group::Group>::Scalar>
|
||||
{
|
||||
/// The representation of a point on this curve in the affine coordinate space.
|
||||
type Affine: CurveAffine<Curve = Self, Scalar = <Self as Curve>::Scalar, Base = <Self as Curve>::Base>
|
||||
+ Add<Output = Self>
|
||||
+ Sub<Output = Self>
|
||||
+ Mul<<Self as Curve>::Scalar, Output = Self>
|
||||
+ Neg<Output = <Self as Curve>::Affine>
|
||||
+ From<Self>;
|
||||
/// The scalar field of this elliptic curve.
|
||||
type Scalar: FieldExt;
|
||||
type ScalarExt: FieldExt;
|
||||
/// The base field over which this elliptic curve is constructed.
|
||||
type Base: FieldExt;
|
||||
|
||||
/// Obtains the additive identity.
|
||||
fn identity() -> Self;
|
||||
|
||||
/// Obtains the base point of the curve.
|
||||
fn generator() -> Self;
|
||||
|
||||
/// Doubles this element.
|
||||
fn double(&self) -> Self;
|
||||
|
||||
/// Returns whether or not this element is the identity.
|
||||
fn is_identity(&self) -> Choice;
|
||||
|
||||
/// Apply the curve endomorphism by multiplying the x-coordinate
|
||||
/// by an element of multiplicative order 3.
|
||||
fn endo(&self) -> Self;
|
||||
|
||||
/// Converts this element into its affine form.
|
||||
fn to_affine(&self) -> Self::Affine;
|
||||
|
||||
/// Return the Jacobian coordinates of this point.
|
||||
fn jacobian_coordinates(&self) -> (Self::Base, Self::Base, Self::Base);
|
||||
|
||||
|
|
@ -84,10 +44,10 @@ pub trait Curve:
|
|||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use halo2::arithmetic::Curve;
|
||||
/// fn pedersen_commitment<C: Curve>(
|
||||
/// x: <C as Curve>::Scalar,
|
||||
/// r: <C as Curve>::Scalar,
|
||||
/// use halo2::arithmetic::CurveExt;
|
||||
/// fn pedersen_commitment<C: CurveExt>(
|
||||
/// x: C::ScalarExt,
|
||||
/// r: C::ScalarExt,
|
||||
/// ) -> C::Affine {
|
||||
/// let hasher = C::hash_to_curve("z.cash:example_pedersen_commitment");
|
||||
/// let g = hasher(b"g");
|
||||
|
|
@ -101,10 +61,6 @@ pub trait Curve:
|
|||
/// always be true unless an "unchecked" API was used.
|
||||
fn is_on_curve(&self) -> Choice;
|
||||
|
||||
/// Converts many elements into their affine form. Panics if the
|
||||
/// sizes of the slices are different.
|
||||
fn batch_normalize(v: &[Self], target: &mut [Self::Affine]);
|
||||
|
||||
/// Returns the curve constant a.
|
||||
fn a() -> Self::Base;
|
||||
|
||||
|
|
@ -119,36 +75,16 @@ pub trait Curve:
|
|||
/// This trait is the affine counterpart to `Curve` and is used for
|
||||
/// serialization, storage in memory, and inspection of $x$ and $y$ coordinates.
|
||||
pub trait CurveAffine:
|
||||
Sized
|
||||
PrimeCurveAffine<Scalar = <Self as CurveAffine>::ScalarExt>
|
||||
+ Default
|
||||
+ Copy
|
||||
+ Clone
|
||||
+ Send
|
||||
+ Sync
|
||||
+ 'static
|
||||
+ Debug
|
||||
+ Add<Output = <Self as CurveAffine>::Curve>
|
||||
+ Sub<Output = <Self as CurveAffine>::Curve>
|
||||
+ Mul<<Self as CurveAffine>::Scalar, Output = <Self as CurveAffine>::Curve>
|
||||
+ Neg<Output = Self>
|
||||
+ PartialEq
|
||||
+ cmp::Eq
|
||||
+ Add<Output = <Self as PrimeCurveAffine>::Curve>
|
||||
+ Sub<Output = <Self as PrimeCurveAffine>::Curve>
|
||||
+ ConditionallySelectable
|
||||
+ ConstantTimeEq
|
||||
+ From<<Self as CurveAffine>::Curve>
|
||||
+ From<<Self as PrimeCurveAffine>::Curve>
|
||||
{
|
||||
/// The representation of a point on this curve in the projective coordinate space.
|
||||
type Curve: Curve<
|
||||
Affine = Self,
|
||||
Scalar = <Self as CurveAffine>::Scalar,
|
||||
Base = <Self as CurveAffine>::Base,
|
||||
> + Mul<<Self as CurveAffine>::Scalar, Output = <Self as CurveAffine>::Curve>
|
||||
+ MulAssign<<Self as CurveAffine>::Scalar>
|
||||
+ AddAssign<Self>
|
||||
+ SubAssign<Self>
|
||||
+ From<Self>;
|
||||
/// The scalar field of this elliptic curve.
|
||||
type Scalar: FieldExt;
|
||||
type ScalarExt: FieldExt;
|
||||
/// The base field over which this elliptic curve is constructed.
|
||||
type Base: FieldExt;
|
||||
|
||||
|
|
@ -159,18 +95,6 @@ pub trait CurveAffine:
|
|||
/// CURVE_ID used for hash-to-curve.
|
||||
const CURVE_ID: &'static str;
|
||||
|
||||
/// Obtains the additive identity.
|
||||
fn identity() -> Self;
|
||||
|
||||
/// Obtains the base point of the curve.
|
||||
fn generator() -> Self;
|
||||
|
||||
/// Returns whether or not this element is the identity.
|
||||
fn is_identity(&self) -> Choice;
|
||||
|
||||
/// Converts this element into its projective form.
|
||||
fn to_curve(&self) -> Self::Curve;
|
||||
|
||||
/// Gets the $(x, y)$ coordinates of this point.
|
||||
fn get_xy(&self) -> CtOption<(Self::Base, Self::Base)>;
|
||||
|
||||
|
|
@ -182,27 +106,19 @@ pub trait CurveAffine:
|
|||
/// always be true unless an "unchecked" API was used.
|
||||
fn is_on_curve(&self) -> Choice;
|
||||
|
||||
/// Attempts to obtain a group element from its compressed 32-byte little
|
||||
/// endian representation.
|
||||
fn from_bytes(bytes: &[u8; 32]) -> CtOption<Self>;
|
||||
|
||||
/// Reads a compressed element from the buffer and attempts to parse it
|
||||
/// using `from_bytes`.
|
||||
fn read<R: Read>(reader: &mut R) -> io::Result<Self> {
|
||||
let mut compressed = [0u8; 32];
|
||||
reader.read_exact(&mut compressed[..])?;
|
||||
let mut compressed = Self::Repr::default();
|
||||
reader.read_exact(compressed.as_mut())?;
|
||||
Option::from(Self::from_bytes(&compressed))
|
||||
.ok_or_else(|| io::Error::new(io::ErrorKind::Other, "invalid point encoding in proof"))
|
||||
}
|
||||
|
||||
/// Obtains the compressed, 32-byte little endian representation of this
|
||||
/// element.
|
||||
fn to_bytes(&self) -> [u8; 32];
|
||||
|
||||
/// Writes an element in compressed form to the buffer.
|
||||
fn write<W: Write>(&self, writer: &mut W) -> io::Result<()> {
|
||||
let compressed = self.to_bytes();
|
||||
writer.write_all(&compressed[..])
|
||||
writer.write_all(compressed.as_ref())
|
||||
}
|
||||
|
||||
/// Attempts to obtain a group element from its uncompressed 64-byte little
|
||||
|
|
|
|||
|
|
@ -15,7 +15,8 @@ pub use fields::*;
|
|||
|
||||
#[test]
|
||||
fn test_endo_consistency() {
|
||||
use crate::arithmetic::{Curve, FieldExt};
|
||||
use crate::arithmetic::{CurveExt, FieldExt};
|
||||
use group::Group;
|
||||
|
||||
let a = pallas::Point::generator();
|
||||
assert_eq!(a * pallas::Scalar::ZETA, a.endo());
|
||||
|
|
|
|||
|
|
@ -3,12 +3,18 @@
|
|||
|
||||
use core::cmp;
|
||||
use core::fmt::Debug;
|
||||
use core::iter::Sum;
|
||||
use core::ops::{Add, Mul, Neg, Sub};
|
||||
use ff::Field;
|
||||
use group::{
|
||||
prime::{PrimeCurve, PrimeCurveAffine, PrimeGroup},
|
||||
Curve as _, Group as _, GroupEncoding,
|
||||
};
|
||||
use rand::RngCore;
|
||||
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption};
|
||||
|
||||
use super::{Fp, Fq};
|
||||
use crate::arithmetic::{Curve, CurveAffine, FieldExt, Group};
|
||||
use crate::arithmetic::{CurveAffine, CurveExt, FieldExt, Group};
|
||||
|
||||
macro_rules! new_curve_impl {
|
||||
(($($privacy:tt)*), $name:ident, $name_affine:ident, $iso:ident, $base:ident, $scalar:ident, $blake2b_personalization:literal,
|
||||
|
|
@ -50,10 +56,21 @@ macro_rules! new_curve_impl {
|
|||
}
|
||||
}
|
||||
|
||||
impl Curve for $name {
|
||||
type Affine = $name_affine;
|
||||
impl group::Group for $name {
|
||||
type Scalar = $scalar;
|
||||
type Base = $base;
|
||||
|
||||
fn random(mut rng: impl RngCore) -> Self {
|
||||
loop {
|
||||
let mut buf = [0; 64];
|
||||
rng.fill_bytes(&mut buf);
|
||||
let p: Option<$name_affine> = $name_affine::from_bytes_wide(&buf).into();
|
||||
if let Some(p) = p {
|
||||
if !bool::from(p.is_identity()) {
|
||||
break p.to_curve();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl_projective_curve_specific!($name, $base, $curve_type);
|
||||
|
||||
|
|
@ -68,22 +85,11 @@ macro_rules! new_curve_impl {
|
|||
fn is_identity(&self) -> Choice {
|
||||
self.z.ct_is_zero()
|
||||
}
|
||||
}
|
||||
|
||||
fn to_affine(&self) -> Self::Affine {
|
||||
let zinv = self.z.invert().unwrap_or($base::zero());
|
||||
let zinv2 = zinv.square();
|
||||
let x = self.x * zinv2;
|
||||
let zinv3 = zinv2 * zinv;
|
||||
let y = self.y * zinv3;
|
||||
|
||||
let tmp = $name_affine {
|
||||
x,
|
||||
y,
|
||||
infinity: Choice::from(0u8),
|
||||
};
|
||||
|
||||
$name_affine::conditional_select(&tmp, &$name_affine::identity(), zinv.ct_is_zero())
|
||||
}
|
||||
impl CurveExt for $name {
|
||||
type ScalarExt = $scalar;
|
||||
type Base = $base;
|
||||
|
||||
impl_projective_curve_ext!($name, $name_affine, $iso, $base, $curve_type);
|
||||
|
||||
|
|
@ -115,8 +121,12 @@ macro_rules! new_curve_impl {
|
|||
.ct_eq(&(z6 * $name::curve_constant_b()))
|
||||
| self.z.ct_is_zero()
|
||||
}
|
||||
}
|
||||
|
||||
fn batch_normalize(p: &[Self], q: &mut [Self::Affine]) {
|
||||
impl group::Curve for $name {
|
||||
type AffineRepr = $name_affine;
|
||||
|
||||
fn batch_normalize(p: &[Self], q: &mut [Self::AffineRepr]) {
|
||||
assert_eq!(p.len(), q.len());
|
||||
|
||||
let mut acc = $base::one();
|
||||
|
|
@ -153,6 +163,45 @@ macro_rules! new_curve_impl {
|
|||
*q = $name_affine::conditional_select(&q, &$name_affine::identity(), skip);
|
||||
}
|
||||
}
|
||||
|
||||
fn to_affine(&self) -> Self::AffineRepr {
|
||||
let zinv = self.z.invert().unwrap_or($base::zero());
|
||||
let zinv2 = zinv.square();
|
||||
let x = self.x * zinv2;
|
||||
let zinv3 = zinv2 * zinv;
|
||||
let y = self.y * zinv3;
|
||||
|
||||
let tmp = $name_affine {
|
||||
x,
|
||||
y,
|
||||
infinity: Choice::from(0u8),
|
||||
};
|
||||
|
||||
$name_affine::conditional_select(&tmp, &$name_affine::identity(), zinv.ct_is_zero())
|
||||
}
|
||||
}
|
||||
|
||||
impl PrimeGroup for $name {}
|
||||
|
||||
impl PrimeCurve for $name {
|
||||
type Affine = $name_affine;
|
||||
}
|
||||
|
||||
impl GroupEncoding for $name {
|
||||
type Repr = [u8; 32];
|
||||
|
||||
fn from_bytes(bytes: &Self::Repr) -> CtOption<Self> {
|
||||
$name_affine::from_bytes(bytes).map(Self::from)
|
||||
}
|
||||
|
||||
fn from_bytes_unchecked(bytes: &Self::Repr) -> CtOption<Self> {
|
||||
// We can't avoid curve checks when parsing a compressed encoding.
|
||||
$name_affine::from_bytes(bytes).map(Self::from)
|
||||
}
|
||||
|
||||
fn to_bytes(&self) -> Self::Repr {
|
||||
$name_affine::from(self).to_bytes()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a $name_affine> for $name {
|
||||
|
|
@ -233,6 +282,18 @@ macro_rules! new_curve_impl {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T> Sum<T> for $name
|
||||
where
|
||||
T: core::borrow::Borrow<$name>,
|
||||
{
|
||||
fn sum<I>(iter: I) -> Self
|
||||
where
|
||||
I: Iterator<Item = T>,
|
||||
{
|
||||
iter.fold(Self::identity(), |acc, item| acc + item.borrow())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b> Add<&'a $name> for &'b $name {
|
||||
type Output = $name;
|
||||
|
||||
|
|
@ -473,13 +534,9 @@ macro_rules! new_curve_impl {
|
|||
}
|
||||
}
|
||||
|
||||
impl CurveAffine for $name_affine {
|
||||
impl PrimeCurveAffine for $name_affine {
|
||||
type Curve = $name;
|
||||
type Scalar = $scalar;
|
||||
type Base = $base;
|
||||
|
||||
const BLAKE2B_PERSONALIZATION: &'static [u8; 16] = $blake2b_personalization;
|
||||
const CURVE_ID: &'static str = $curve_id;
|
||||
|
||||
impl_affine_curve_specific!($name, $base, $curve_type);
|
||||
|
||||
|
|
@ -495,12 +552,6 @@ macro_rules! new_curve_impl {
|
|||
self.infinity
|
||||
}
|
||||
|
||||
fn is_on_curve(&self) -> Choice {
|
||||
// y^2 - x^3 - ax ?= b
|
||||
(self.y.square() - (self.x.square() + &$name::curve_constant_a()) * self.x).ct_eq(&$name::curve_constant_b())
|
||||
| self.infinity
|
||||
}
|
||||
|
||||
fn to_curve(&self) -> Self::Curve {
|
||||
$name {
|
||||
x: self.x,
|
||||
|
|
@ -508,17 +559,10 @@ macro_rules! new_curve_impl {
|
|||
z: $base::conditional_select(&$base::one(), &$base::zero(), self.infinity),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_xy(&self) -> CtOption<(Self::Base, Self::Base)> {
|
||||
CtOption::new((self.x, self.y), !self.is_identity())
|
||||
}
|
||||
|
||||
fn from_xy(x: Self::Base, y: Self::Base) -> CtOption<Self> {
|
||||
let p = $name_affine {
|
||||
x, y, infinity: 0u8.into()
|
||||
};
|
||||
CtOption::new(p, p.is_on_curve())
|
||||
}
|
||||
impl GroupEncoding for $name_affine {
|
||||
type Repr = [u8; 32];
|
||||
|
||||
fn from_bytes(bytes: &[u8; 32]) -> CtOption<Self> {
|
||||
let mut tmp = *bytes;
|
||||
|
|
@ -546,6 +590,11 @@ macro_rules! new_curve_impl {
|
|||
})
|
||||
}
|
||||
|
||||
fn from_bytes_unchecked(bytes: &Self::Repr) -> CtOption<Self> {
|
||||
// We can't avoid curve checks when parsing a compressed encoding.
|
||||
Self::from_bytes(bytes)
|
||||
}
|
||||
|
||||
fn to_bytes(&self) -> [u8; 32] {
|
||||
// TODO: not constant time
|
||||
if bool::from(self.is_identity()) {
|
||||
|
|
@ -558,6 +607,31 @@ macro_rules! new_curve_impl {
|
|||
xbytes
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl CurveAffine for $name_affine {
|
||||
type ScalarExt = $scalar;
|
||||
type Base = $base;
|
||||
|
||||
const BLAKE2B_PERSONALIZATION: &'static [u8; 16] = $blake2b_personalization;
|
||||
const CURVE_ID: &'static str = $curve_id;
|
||||
|
||||
fn is_on_curve(&self) -> Choice {
|
||||
// y^2 - x^3 - ax ?= b
|
||||
(self.y.square() - (self.x.square() + &$name::curve_constant_a()) * self.x).ct_eq(&$name::curve_constant_b())
|
||||
| self.infinity
|
||||
}
|
||||
|
||||
fn get_xy(&self) -> CtOption<(Self::Base, Self::Base)> {
|
||||
CtOption::new((self.x, self.y), !self.is_identity())
|
||||
}
|
||||
|
||||
fn from_xy(x: Self::Base, y: Self::Base) -> CtOption<Self> {
|
||||
let p = $name_affine {
|
||||
x, y, infinity: 0u8.into()
|
||||
};
|
||||
CtOption::new(p, p.is_on_curve())
|
||||
}
|
||||
|
||||
fn from_bytes_wide(bytes: &[u8; 64]) -> CtOption<Self> {
|
||||
let mut xbytes = [0u8; 32];
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
use subtle::ConstantTimeEq;
|
||||
|
||||
use crate::arithmetic::{Curve, FieldExt};
|
||||
use crate::arithmetic::{CurveExt, FieldExt};
|
||||
|
||||
/// Hashes over a message and writes the output to all of `buf`.
|
||||
pub fn hash_to_field<F: FieldExt>(
|
||||
|
|
@ -72,7 +72,7 @@ pub fn hash_to_field<F: FieldExt>(
|
|||
}
|
||||
|
||||
/// Implements a degree 3 isogeny map.
|
||||
pub fn iso_map<F: FieldExt, C: Curve<Base = F>, I: Curve<Base = F>>(
|
||||
pub fn iso_map<F: FieldExt, C: CurveExt<Base = F>, I: CurveExt<Base = F>>(
|
||||
p: &I,
|
||||
iso: &[C::Base; 13],
|
||||
) -> C {
|
||||
|
|
@ -99,7 +99,7 @@ pub fn iso_map<F: FieldExt, C: Curve<Base = F>, I: Curve<Base = F>>(
|
|||
C::new_jacobian(xo, yo, zo).unwrap()
|
||||
}
|
||||
|
||||
pub fn map_to_curve_simple_swu<F: FieldExt, C: Curve<Base = F>, I: Curve<Base = F>>(
|
||||
pub fn map_to_curve_simple_swu<F: FieldExt, C: CurveExt<Base = F>, I: CurveExt<Base = F>>(
|
||||
u: &F,
|
||||
theta: F,
|
||||
z: F,
|
||||
|
|
|
|||
|
|
@ -16,7 +16,8 @@ pub type Affine = EpAffine;
|
|||
|
||||
#[test]
|
||||
fn test_iso_map() {
|
||||
use crate::arithmetic::Curve;
|
||||
use crate::arithmetic::CurveExt;
|
||||
use group::Group;
|
||||
|
||||
// This is a regression test (it's the same input to iso_map as for hash_to_curve
|
||||
// with domain prefix "z.cash:test", Shake128, and input b"hello"). We don't
|
||||
|
|
@ -64,7 +65,8 @@ fn test_iso_map() {
|
|||
|
||||
#[test]
|
||||
fn test_iso_map_identity() {
|
||||
use crate::arithmetic::Curve;
|
||||
use crate::arithmetic::CurveExt;
|
||||
use group::Group;
|
||||
|
||||
let r = super::IsoEp::new_jacobian(
|
||||
Base::from_raw([
|
||||
|
|
@ -97,7 +99,7 @@ fn test_iso_map_identity() {
|
|||
|
||||
#[test]
|
||||
fn test_map_to_curve_simple_swu() {
|
||||
use crate::arithmetic::Curve;
|
||||
use crate::arithmetic::CurveExt;
|
||||
use crate::pasta::curves::IsoEp;
|
||||
use crate::pasta::hashtocurve::map_to_curve_simple_swu;
|
||||
|
||||
|
|
@ -131,7 +133,8 @@ fn test_map_to_curve_simple_swu() {
|
|||
|
||||
#[test]
|
||||
fn test_hash_to_curve() {
|
||||
use crate::arithmetic::Curve;
|
||||
use crate::arithmetic::CurveExt;
|
||||
use group::Group;
|
||||
|
||||
// This test vector is chosen so that the first map_to_curve_simple_swu takes the gx1 square
|
||||
// "branch" and the second takes the gx1 non-square "branch" (opposite to the Vesta test vector).
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ pub type Affine = EqAffine;
|
|||
|
||||
#[test]
|
||||
fn test_map_to_curve_simple_swu() {
|
||||
use crate::arithmetic::Curve;
|
||||
use crate::arithmetic::CurveExt;
|
||||
use crate::pasta::curves::IsoEq;
|
||||
use crate::pasta::hashtocurve::map_to_curve_simple_swu;
|
||||
|
||||
|
|
@ -50,7 +50,7 @@ fn test_map_to_curve_simple_swu() {
|
|||
|
||||
#[test]
|
||||
fn test_hash_to_curve() {
|
||||
use crate::arithmetic::Curve;
|
||||
use crate::arithmetic::CurveExt;
|
||||
|
||||
// This test vector is chosen so that the first map_to_curve_simple_swu takes the gx1 non-square
|
||||
// "branch" and the second takes the gx1 square "branch" (opposite to the Pallas test vector).
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ impl<C: CurveAffine> VerifyingKey<C> {
|
|||
/// Writes a verifying key to a buffer.
|
||||
pub fn write<W: io::Write>(&self, writer: &mut W) -> io::Result<()> {
|
||||
for commitment in &self.fixed_commitments {
|
||||
writer.write_all(&commitment.to_bytes())?;
|
||||
writer.write_all(commitment.to_bytes().as_ref())?;
|
||||
}
|
||||
for permutation in &self.permutations {
|
||||
permutation.write(writer)?;
|
||||
|
|
@ -190,7 +190,7 @@ type ChallengeX<F> = ChallengeScalar<F, X>;
|
|||
|
||||
#[test]
|
||||
fn test_proving() {
|
||||
use crate::arithmetic::{Curve, FieldExt};
|
||||
use crate::arithmetic::FieldExt;
|
||||
use crate::dev::MockProver;
|
||||
use crate::pasta::{EqAffine, Fp};
|
||||
use crate::poly::{
|
||||
|
|
@ -199,6 +199,7 @@ fn test_proving() {
|
|||
};
|
||||
use crate::transcript::{Blake2bRead, Blake2bWrite};
|
||||
use circuit::{Advice, Column, Fixed};
|
||||
use group::Curve;
|
||||
use std::marker::PhantomData;
|
||||
const K: u32 = 5;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
use ff::Field;
|
||||
use group::Curve;
|
||||
|
||||
use super::{
|
||||
circuit::{Advice, Assignment, Circuit, Column, ConstraintSystem, Fixed},
|
||||
permutation, Error, LagrangeCoeff, Polynomial, ProvingKey, VerifyingKey,
|
||||
};
|
||||
use crate::arithmetic::{Curve, CurveAffine};
|
||||
use crate::arithmetic::CurveAffine;
|
||||
use crate::poly::{
|
||||
commitment::{Blind, Params},
|
||||
EvaluationDomain, Rotation,
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use super::super::{
|
|||
};
|
||||
use super::Argument;
|
||||
use crate::{
|
||||
arithmetic::{eval_polynomial, parallelize, BatchInvert, Curve, CurveAffine, FieldExt},
|
||||
arithmetic::{eval_polynomial, parallelize, BatchInvert, CurveAffine, FieldExt},
|
||||
poly::{
|
||||
commitment::{Blind, Params},
|
||||
multiopen::ProverQuery,
|
||||
|
|
@ -13,6 +13,7 @@ use crate::{
|
|||
transcript::TranscriptWrite,
|
||||
};
|
||||
use ff::Field;
|
||||
use group::Curve;
|
||||
use std::{
|
||||
collections::BTreeMap,
|
||||
iter,
|
||||
|
|
@ -86,7 +87,7 @@ impl<F: FieldExt> Argument<F> {
|
|||
transcript: &mut T,
|
||||
) -> Result<Permuted<C>, Error>
|
||||
where
|
||||
C: CurveAffine<Scalar = F>,
|
||||
C: CurveAffine<ScalarExt = F>,
|
||||
C::Curve: Mul<F, Output = C::Curve> + MulAssign<F>,
|
||||
{
|
||||
// Closure to get values of expressions and compress them
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
use ff::Field;
|
||||
use group::Curve;
|
||||
|
||||
use super::{Argument, ProvingKey, VerifyingKey};
|
||||
use crate::{
|
||||
arithmetic::{Curve, CurveAffine, FieldExt},
|
||||
arithmetic::{CurveAffine, FieldExt},
|
||||
plonk::{circuit::ConstraintSystem, Error},
|
||||
poly::{
|
||||
commitment::{Blind, Params},
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
use ff::Field;
|
||||
use group::Curve;
|
||||
use std::iter;
|
||||
|
||||
use super::super::circuit::Any;
|
||||
use super::{Argument, ProvingKey};
|
||||
use crate::{
|
||||
arithmetic::{eval_polynomial, parallelize, BatchInvert, Curve, CurveAffine, FieldExt},
|
||||
arithmetic::{eval_polynomial, parallelize, BatchInvert, CurveAffine, FieldExt},
|
||||
plonk::{self, ChallengeBeta, ChallengeGamma, ChallengeX, Error},
|
||||
poly::{
|
||||
commitment::{Blind, Params},
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use ff::Field;
|
||||
use group::Curve;
|
||||
use std::iter;
|
||||
|
||||
use super::{
|
||||
|
|
@ -6,7 +7,7 @@ use super::{
|
|||
lookup, permutation, vanishing, ChallengeBeta, ChallengeGamma, ChallengeTheta, ChallengeX,
|
||||
ChallengeY, Error, ProvingKey,
|
||||
};
|
||||
use crate::arithmetic::{eval_polynomial, Curve, CurveAffine, FieldExt};
|
||||
use crate::arithmetic::{eval_polynomial, CurveAffine, FieldExt};
|
||||
use crate::poly::{
|
||||
commitment::{Blind, Params},
|
||||
multiopen::{self, ProverQuery},
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
use group::Curve;
|
||||
|
||||
use super::Argument;
|
||||
use crate::{
|
||||
arithmetic::{eval_polynomial, Curve, CurveAffine, FieldExt},
|
||||
arithmetic::{eval_polynomial, CurveAffine, FieldExt},
|
||||
plonk::{ChallengeX, ChallengeY, Error},
|
||||
poly::{
|
||||
commitment::{Blind, Params},
|
||||
|
|
|
|||
|
|
@ -6,10 +6,10 @@
|
|||
use blake2b_simd::{Params as Blake2bParams, State as Blake2bState};
|
||||
|
||||
use super::{Coeff, LagrangeCoeff, Polynomial};
|
||||
use crate::arithmetic::{best_fft, best_multiexp, parallelize, Curve, CurveAffine, FieldExt};
|
||||
use crate::arithmetic::{best_fft, best_multiexp, parallelize, CurveAffine, FieldExt, Group};
|
||||
|
||||
use ff::{Field, PrimeField};
|
||||
use std::convert::TryInto;
|
||||
use group::{prime::PrimeCurveAffine, Curve};
|
||||
use std::ops::{Add, AddAssign, Mul, MulAssign};
|
||||
|
||||
mod msm;
|
||||
|
|
@ -36,7 +36,10 @@ pub struct Params<C: CurveAffine> {
|
|||
impl<C: CurveAffine> Params<C> {
|
||||
/// Initializes parameters for the curve, given a random oracle to draw
|
||||
/// points from.
|
||||
pub fn new(k: u32) -> Self {
|
||||
pub fn new(k: u32) -> Self
|
||||
where
|
||||
<C as PrimeCurveAffine>::Curve: Group,
|
||||
{
|
||||
// This is usually a limitation on the curve, but we also want 32-bit
|
||||
// architectures to be supported.
|
||||
assert!(k < 32);
|
||||
|
|
@ -50,7 +53,9 @@ impl<C: CurveAffine> Params<C> {
|
|||
loop {
|
||||
let mut hasher = hasher.clone();
|
||||
hasher.update(&(trial.to_le_bytes())[..]);
|
||||
let p = C::from_bytes(&hasher.finalize().as_bytes().try_into().unwrap());
|
||||
let mut repr = C::Repr::default();
|
||||
repr.as_mut().copy_from_slice(hasher.finalize().as_bytes());
|
||||
let p = C::from_bytes(&repr);
|
||||
if bool::from(p.is_some()) {
|
||||
break p.unwrap();
|
||||
}
|
||||
|
|
@ -83,7 +88,7 @@ impl<C: CurveAffine> Params<C> {
|
|||
|
||||
// Let's evaluate all of the Lagrange basis polynomials
|
||||
// using an inverse FFT.
|
||||
let mut alpha_inv = C::Scalar::ROOT_OF_UNITY_INV;
|
||||
let mut alpha_inv = <<C as PrimeCurveAffine>::Curve as Group>::Scalar::ROOT_OF_UNITY_INV;
|
||||
for _ in k..C::Scalar::S {
|
||||
alpha_inv = alpha_inv.square();
|
||||
}
|
||||
|
|
@ -191,13 +196,13 @@ impl<C: CurveAffine> Params<C> {
|
|||
pub fn write<W: io::Write>(&self, writer: &mut W) -> io::Result<()> {
|
||||
writer.write_all(&self.k.to_le_bytes())?;
|
||||
for g_element in &self.g {
|
||||
writer.write_all(&g_element.to_bytes())?;
|
||||
writer.write_all(g_element.to_bytes().as_ref())?;
|
||||
}
|
||||
for g_lagrange_element in &self.g_lagrange {
|
||||
writer.write_all(&g_lagrange_element.to_bytes())?;
|
||||
writer.write_all(g_lagrange_element.to_bytes().as_ref())?;
|
||||
}
|
||||
writer.write_all(&self.h.to_bytes())?;
|
||||
writer.write_all(&self.u.to_bytes())?;
|
||||
writer.write_all(self.h.to_bytes().as_ref())?;
|
||||
writer.write_all(self.u.to_bytes().as_ref())?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use super::Params;
|
||||
use crate::arithmetic::{best_multiexp, parallelize, Curve, CurveAffine};
|
||||
use crate::arithmetic::{best_multiexp, parallelize, CurveAffine};
|
||||
use ff::Field;
|
||||
use group::Group;
|
||||
|
||||
/// A multiscalar multiplication in the polynomial commitment scheme
|
||||
#[derive(Debug, Clone)]
|
||||
|
|
|
|||
|
|
@ -3,10 +3,11 @@ use ff::Field;
|
|||
use super::super::{Coeff, Polynomial};
|
||||
use super::{Blind, Params};
|
||||
use crate::arithmetic::{
|
||||
best_multiexp, compute_inner_product, eval_polynomial, parallelize, Curve, CurveAffine,
|
||||
FieldExt,
|
||||
best_multiexp, compute_inner_product, eval_polynomial, parallelize, CurveAffine, FieldExt,
|
||||
};
|
||||
use crate::transcript::{Challenge, ChallengeScalar, TranscriptWrite};
|
||||
|
||||
use group::Curve;
|
||||
use std::io;
|
||||
|
||||
/// Create a polynomial commitment opening proof for the polynomial defined
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
use ff::Field;
|
||||
use group::Curve;
|
||||
|
||||
use super::super::Error;
|
||||
use super::{Params, MSM};
|
||||
use crate::transcript::{Challenge, ChallengeScalar, TranscriptRead};
|
||||
|
||||
use crate::arithmetic::{best_multiexp, BatchInvert, Curve, CurveAffine};
|
||||
use crate::arithmetic::{best_multiexp, BatchInvert, CurveAffine};
|
||||
|
||||
/// A guard returned by the verifier
|
||||
#[derive(Debug, Clone)]
|
||||
|
|
|
|||
|
|
@ -206,8 +206,10 @@ where
|
|||
|
||||
#[test]
|
||||
fn test_roundtrip() {
|
||||
use group::Curve;
|
||||
|
||||
use super::commitment::{Blind, Params};
|
||||
use crate::arithmetic::{eval_polynomial, Curve, FieldExt};
|
||||
use crate::arithmetic::{eval_polynomial, FieldExt};
|
||||
use crate::pasta::{EqAffine, Fp};
|
||||
|
||||
const K: u32 = 4;
|
||||
|
|
|
|||
|
|
@ -7,10 +7,11 @@ use super::{
|
|||
Query,
|
||||
};
|
||||
|
||||
use crate::arithmetic::{eval_polynomial, kate_division, Curve, CurveAffine, FieldExt};
|
||||
use crate::arithmetic::{eval_polynomial, kate_division, CurveAffine, FieldExt};
|
||||
use crate::transcript::TranscriptWrite;
|
||||
|
||||
use ff::Field;
|
||||
use group::Curve;
|
||||
use std::io;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
|
|
|
|||
|
|
@ -69,8 +69,8 @@ impl<R: Read, C: CurveAffine> Blake2bRead<R, C> {
|
|||
|
||||
impl<R: Read, C: CurveAffine> TranscriptRead<C> for Blake2bRead<R, C> {
|
||||
fn read_point(&mut self) -> io::Result<C> {
|
||||
let mut compressed = [0u8; 32];
|
||||
self.reader.read_exact(&mut compressed[..])?;
|
||||
let mut compressed = C::Repr::default();
|
||||
self.reader.read_exact(compressed.as_mut())?;
|
||||
let point: C = Option::from(C::from_bytes(&compressed)).ok_or_else(|| {
|
||||
io::Error::new(io::ErrorKind::Other, "invalid point encoding in proof")
|
||||
})?;
|
||||
|
|
@ -154,7 +154,7 @@ impl<W: Write, C: CurveAffine> TranscriptWrite<C> for Blake2bWrite<W, C> {
|
|||
fn write_point(&mut self, point: C) -> io::Result<()> {
|
||||
self.common_point(point)?;
|
||||
let compressed = point.to_bytes();
|
||||
self.writer.write_all(&compressed[..])
|
||||
self.writer.write_all(compressed.as_ref())
|
||||
}
|
||||
fn write_scalar(&mut self, scalar: C::Scalar) -> io::Result<()> {
|
||||
self.common_scalar(scalar)?;
|
||||
|
|
|
|||
Loading…
Reference in a new issue