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