Skip to content

Commit

Permalink
add extension field in brakedown
Browse files Browse the repository at this point in the history
  • Loading branch information
xiangxiecrypto committed Jul 26, 2024
1 parent bc3996f commit aa7d949
Show file tree
Hide file tree
Showing 14 changed files with 322 additions and 143 deletions.
23 changes: 1 addition & 22 deletions algebra/src/baby_bear/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use crate::{
};

/// Implementation of BabyBear field.
#[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
#[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Serialize, Deserialize)]
pub struct BabyBear(u32);

impl Field for BabyBear {
Expand Down Expand Up @@ -354,24 +354,3 @@ impl TwoAdicField for BabyBear {
}
}
}

impl Serialize for BabyBear {
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_u32(self.value())
}
}

impl<'de> Deserialize<'de> for BabyBear {
#[inline]
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let value = u32::deserialize(deserializer)?;
Ok(Self::new(value))
}
}
63 changes: 61 additions & 2 deletions algebra/src/extension/binomial_extension.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use core::fmt;
use std::{
array,
fmt::Display,
Expand All @@ -8,6 +9,11 @@ use itertools::Itertools;
use num_traits::{Inv, One, Pow, Zero};
use rand::{CryptoRng, Rng};
use rand_distr::{Distribution, Standard};
use serde::{
de::{SeqAccess, Visitor},
ser::SerializeSeq,
Deserialize, Deserializer, Serialize, Serializer,
};

use crate::{
field_to_array, powers, AbstractExtensionField, ExtensionField, Field, FieldUniformSampler,
Expand Down Expand Up @@ -588,7 +594,60 @@ impl<F: Field + HasTwoAdicBionmialExtension<D> + Packable, const D: usize> TwoAd
}
}

///Section 11.3.6b in Handbook of Elliptic and Hyperelliptic Curve Cryptography.
impl<F: Serialize, const D: usize> Serialize for BinomialExtensionField<F, D> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut seq = serializer.serialize_seq(Some(D))?;
for item in &self.value {
seq.serialize_element(item)?;
}
seq.end()
}
}

impl<'de, F: Deserialize<'de> + Default + Copy, const D: usize> Deserialize<'de>
for BinomialExtensionField<F, D>
{
fn deserialize<DE>(deserializer: DE) -> Result<Self, DE::Error>
where
DE: Deserializer<'de>,
{
struct ArrayVisitor<F, const D: usize> {
marker: std::marker::PhantomData<F>,
}

impl<'de, F: Copy + Deserialize<'de> + Default, const D: usize> Visitor<'de>
for ArrayVisitor<F, D>
{
type Value = BinomialExtensionField<F, D>;

fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str(&format!("an array of length {}", D))
}

fn visit_seq<V>(self, mut seq: V) -> Result<Self::Value, V::Error>
where
V: SeqAccess<'de>,
{
let mut value = [F::default(); D];
for (i, v) in value.iter_mut().enumerate().take(D) {
*v = seq
.next_element()?
.ok_or_else(|| serde::de::Error::invalid_length(i, &self))?;
}
Ok(BinomialExtensionField { value })
}
}

deserializer.deserialize_seq(ArrayVisitor {
marker: std::marker::PhantomData,
})
}
}

/// Section 11.3.6b in Handbook of Elliptic and Hyperelliptic Curve Cryptography.
#[inline]
fn qudratic_inv<F: Field>(a: &[F], w: F) -> [F; 2] {
let scalar = (a[0] * a[0] - w * a[1] * a[1]).inv();
Expand All @@ -608,7 +667,7 @@ fn cubic_inv<F: Field>(a: &[F], w: F) -> [F; 3] {
- (F::one() + F::one() + F::one()) * a2_w * a0_a1)
.inv();

//scalar*[a0^2-wa1a2, wa2^2-a0a1, a1^2-a0a2]
// scalar*[a0^2-wa1a2, wa2^2-a0a1, a1^2-a0a2]
[
scalar * (a0_square - a[1] * a2_w),
scalar * (a2_w * a[2] - a0_a1),
Expand Down
23 changes: 1 addition & 22 deletions algebra/src/goldilocks/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use crate::{
};

/// Implementation of Goldilocks field
#[derive(Debug, Default, Clone, Copy)]
#[derive(Debug, Default, Clone, Copy, Serialize, Deserialize)]
pub struct Goldilocks(u64);

impl Goldilocks {
Expand Down Expand Up @@ -367,24 +367,3 @@ fn exp_power_of_2<F: Field>(x: F, power_log: usize) -> F {
}
res
}

impl Serialize for Goldilocks {
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_u64(self.value())
}
}

impl<'de> Deserialize<'de> for Goldilocks {
#[inline]
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let value = u64::deserialize(deserializer)?;
Ok(Self::new(value))
}
}
33 changes: 32 additions & 1 deletion algebra/src/polynomial/multivariate/multilinear/dense.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::slice::{Iter, IterMut};
use num_traits::Zero;
use rand_distr::Distribution;

use crate::{DecomposableField, Field, FieldUniformSampler};
use crate::{AbstractExtensionField, DecomposableField, Field, FieldUniformSampler};

use super::MultilinearExtension;
use std::rc::Rc;
Expand Down Expand Up @@ -78,6 +78,37 @@ impl<F: Field> DenseMultilinearExtension<F> {
);
(left, right)
}

/// Evaluate a point in the extension field.
#[inline]
pub fn evaluate_ext<EF>(&self, ext_point: &[EF]) -> EF
where
EF: AbstractExtensionField<F>,
{
assert_eq!(ext_point.len(), self.num_vars, "The point size is invalid.");
let mut poly: Vec<_> = self
.evaluations
.iter()
.map(|&eval| EF::from_base(eval))
.collect();
let nv = self.num_vars;
let dim = ext_point.len();
// evaluate nv variable of partial point from left to right
// with dim rounds and \sum_{i=1}^{dim} 2^(nv - i)
// (If dim = nv, then the complexity is 2^{nv}.)
for i in 1..dim + 1 {
// fix a single variable to evaluate (1 << (nv - i)) evaluations from the last round
// with complexity of 2^(1 << (nv - i)) field multiplications
let r = ext_point[i - 1];
for b in 0..(1 << (nv - i)) {
let left = poly[b << 1];
let right = poly[(b << 1) + 1];
poly[b] = r * (right - left) + left;
}
}
poly.truncate(1 << (nv - dim));
poly[0]
}
}

impl<F: DecomposableField> DenseMultilinearExtension<F> {
Expand Down
33 changes: 18 additions & 15 deletions pcs/benches/brakedown_pcs.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use std::time::Duration;

use algebra::{
derive::Field, utils::Transcript, DenseMultilinearExtension, FieldUniformSampler,
MultilinearExtension,
utils::Transcript, BabyBear, BabyBearExetension, DenseMultilinearExtension, FieldUniformSampler,
};
use criterion::{criterion_group, criterion_main, Criterion};
use pcs::{
Expand All @@ -15,9 +14,7 @@ use pcs::{
use rand::Rng;
use sha2::Sha256;

#[derive(Field)]
#[modulus = 1152921504606846883]
pub struct FF(u64);
type FF = BabyBear;

pub fn criterion_benchmark(c: &mut Criterion) {
let num_vars = 20;
Expand All @@ -30,18 +27,19 @@ pub fn criterion_benchmark(c: &mut Criterion) {

let code_spec = ExpanderCodeSpec::new(128, 0.1195, 0.0284, 1.9, 60, 10);

let point: Vec<FF> = rand::thread_rng()
let point: Vec<BabyBearExetension> = rand::thread_rng()
.sample_iter(FieldUniformSampler::new())
.take(num_vars)
.collect();

let eval = poly.evaluate(&point);
let eval = poly.evaluate_ext(&point);

type Hash = Sha256;
let pp = BrakedownPCS::<FF, Hash, ExpanderCode<FF>, ExpanderCodeSpec>::setup(
num_vars,
Some(code_spec),
);
let pp =
BrakedownPCS::<FF, Hash, ExpanderCode<FF>, ExpanderCodeSpec, BabyBearExetension>::setup(
num_vars,
Some(code_spec),
);

let mut trans = Transcript::<FF>::new();
let mut comm = BrakedownPolyCommitment::default();
Expand All @@ -50,14 +48,19 @@ pub fn criterion_benchmark(c: &mut Criterion) {

c.bench_function(&format!("num_vars: {}, commit time: ", num_vars), |b| {
b.iter(|| {
(comm, state) =
BrakedownPCS::<FF, Hash, ExpanderCode<FF>, ExpanderCodeSpec>::commit(&pp, &poly)
(comm, state) = BrakedownPCS::<
FF,
Hash,
ExpanderCode<FF>,
ExpanderCodeSpec,
BabyBearExetension,
>::commit(&pp, &poly)
})
});

c.bench_function(&format!("num_vars: {}, opening time: ", num_vars), |b| {
b.iter(|| {
proof = BrakedownPCS::<FF, Hash, ExpanderCode<FF>, ExpanderCodeSpec>::open(
proof = BrakedownPCS::<FF, Hash, ExpanderCode<FF>, ExpanderCodeSpec, BabyBearExetension>::open(
&pp, &comm, &state, &point, &mut trans,
)
})
Expand All @@ -67,7 +70,7 @@ pub fn criterion_benchmark(c: &mut Criterion) {
&format!("num_vars: {}, verification time: ", num_vars),
|b| {
b.iter(|| {
BrakedownPCS::<FF, Hash, ExpanderCode<FF>, ExpanderCodeSpec>::verify(
BrakedownPCS::<FF, Hash, ExpanderCode<FF>, ExpanderCodeSpec,BabyBearExetension>::verify(
&pp, &comm, &point, eval, &proof, &mut trans,
)
})
Expand Down
22 changes: 10 additions & 12 deletions pcs/examples/brakedown_pcs.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use std::time::Instant;

use algebra::{
derive::Field, utils::Transcript, DenseMultilinearExtension, FieldUniformSampler,
MultilinearExtension,
utils::Transcript, BabyBear, BabyBearExetension, DenseMultilinearExtension, FieldUniformSampler,
};
use pcs::{
multilinear::brakedown::BrakedownPCS,
Expand All @@ -12,12 +11,11 @@ use pcs::{
use rand::Rng;
use sha2::Sha256;

#[derive(Field)]
#[modulus = 1152921504606846883]
pub struct FF(u64);
type FF = BabyBear;
type EF = BabyBearExetension;

fn main() {
let num_vars = 20;
let num_vars = 24;
let evaluations: Vec<FF> = rand::thread_rng()
.sample_iter(FieldUniformSampler::new())
.take(1 << num_vars)
Expand All @@ -30,7 +28,7 @@ fn main() {
type Hash = Sha256;

let start = Instant::now();
let pp = BrakedownPCS::<FF, Hash, ExpanderCode<FF>, ExpanderCodeSpec>::setup(
let pp = BrakedownPCS::<FF, Hash, ExpanderCode<FF>, ExpanderCodeSpec, EF>::setup(
num_vars,
Some(code_spec),
);
Expand All @@ -40,26 +38,26 @@ fn main() {

let start = Instant::now();
let (comm, state) =
BrakedownPCS::<FF, Hash, ExpanderCode<FF>, ExpanderCodeSpec>::commit(&pp, &poly);
BrakedownPCS::<FF, Hash, ExpanderCode<FF>, ExpanderCodeSpec, EF>::commit(&pp, &poly);
println!("commit time: {:?} ms", start.elapsed().as_millis());

let point: Vec<FF> = rand::thread_rng()
let point: Vec<EF> = rand::thread_rng()
.sample_iter(FieldUniformSampler::new())
.take(num_vars)
.collect();

let start = Instant::now();
let proof = BrakedownPCS::<FF, Hash, ExpanderCode<FF>, ExpanderCodeSpec>::open(
let proof = BrakedownPCS::<FF, Hash, ExpanderCode<FF>, ExpanderCodeSpec, EF>::open(
&pp, &comm, &state, &point, &mut trans,
);
println!("open time: {:?} ms", start.elapsed().as_millis());

let eval = poly.evaluate(&point);
let eval = poly.evaluate_ext(&point);

let mut trans = Transcript::<FF>::new();

let start = Instant::now();
let check = BrakedownPCS::<FF, Hash, ExpanderCode<FF>, ExpanderCodeSpec>::verify(
let check = BrakedownPCS::<FF, Hash, ExpanderCode<FF>, ExpanderCodeSpec, EF>::verify(
&pp, &comm, &point, eval, &proof, &mut trans,
);
println!("verify time: {:?} ms", start.elapsed().as_millis());
Expand Down
10 changes: 6 additions & 4 deletions pcs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub mod utils;

use algebra::{utils::Transcript, Field, MultilinearExtension};

type Point<F, P> = <P as MultilinearExtension<F>>::Point;
// type Point<F, P> = <P as MultilinearExtension<F>>::Point;

/// Polymomial Commitment Scheme
pub trait PolynomialCommitmentScheme<F: Field, S> {
Expand All @@ -24,6 +24,8 @@ pub trait PolynomialCommitmentScheme<F: Field, S> {
type CommitmentState;
/// Opening Proof
type Proof;
/// Point
type Point;

/// The Setup phase.
fn setup(num_vars: usize, code_spec: Option<S>) -> Self::Parameters;
Expand All @@ -39,16 +41,16 @@ pub trait PolynomialCommitmentScheme<F: Field, S> {
pp: &Self::Parameters,
commitment: &Self::Commitment,
state: &Self::CommitmentState,
point: &Point<F, Self::Polynomial>,
points: &[Self::Point],
trans: &mut Transcript<F>,
) -> Self::Proof;

/// The Verification phase.
fn verify(
pp: &Self::Parameters,
commitment: &Self::Commitment,
point: &Point<F, Self::Polynomial>,
eval: F,
points: &[Self::Point],
eval: Self::Point,
proof: &Self::Proof,
trans: &mut Transcript<F>,
) -> bool;
Expand Down
Loading

0 comments on commit aa7d949

Please sign in to comment.