Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added serialization support for compatibility with latest plonky2 head #3

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "plonky2_ecdsa"
description = "ECDSA gadget for Plonky2"
version = "0.1.0"
version = "0.1.3"
license = "MIT OR Apache-2.0"
edition = "2021"

Expand All @@ -11,10 +11,10 @@ parallel = ["plonky2_maybe_rayon/parallel", "plonky2/parallel"]
[dependencies]
anyhow = { version = "1.0.40", default-features = false }
itertools = { version = "0.10.0", default-features = false }
plonky2_maybe_rayon = { version = "0.1.0", default-features = false }
plonky2_maybe_rayon = { git = "https://github.com/mir-protocol/plonky2", rev = "3de92d9ed1721cec133e4e1e1b3ec7facb756ccf", default-features = false }
num = { version = "0.4.0", default-features = false }
plonky2 = { version = "0.1.2", default-features = false }
plonky2_u32 = { version = "0.1.0", default-features = false }
plonky2 = { git = "https://github.com/mir-protocol/plonky2", rev = "3de92d9ed1721cec133e4e1e1b3ec7facb756ccf", default-features = false }
plonky2_u32 = { git = "https://github.com/cf/plonky2-u32", rev = "5b3cb748be32844ae449c62eae6f08278e4b4911", default-features = false }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For all of these (especially your forked repo here), is there a reason for using these specific commits?

serde = { version = "1.0", default-features = false, features = ["derive"] }

[dev-dependencies]
Expand Down
38 changes: 37 additions & 1 deletion src/gadgets/biguint.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use alloc::vec;
use alloc::vec::Vec;
use itertools::Itertools;
use core::marker::PhantomData;
use plonky2::util::serialization::{Buffer, IoResult, Read, Write};

use alloc::string::{String, ToString};
use num::{BigUint, Integer, Zero};
use plonky2::field::extension::Extendable;
use plonky2::field::types::{PrimeField, PrimeField64};
Expand All @@ -13,7 +16,6 @@ use plonky2::plonk::circuit_builder::CircuitBuilder;
use plonky2_u32::gadgets::arithmetic_u32::{CircuitBuilderU32, U32Target};
use plonky2_u32::gadgets::multiple_comparison::list_le_u32_circuit;
use plonky2_u32::witness::{GeneratedValuesU32, WitnessU32};

#[derive(Clone, Debug)]
pub struct BigUintTarget {
pub limbs: Vec<U32Target>,
Expand All @@ -27,6 +29,15 @@ impl BigUintTarget {
pub fn get_limb(&self, i: usize) -> U32Target {
self.limbs[i]
}
pub fn write_to_serializer(&self, dst: &mut Vec<u8>) -> IoResult<()> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: spacing between functions

dst.write_target_vec(&self.limbs.iter().map(|l| l.0).collect_vec())
}
pub fn deserialize(src: &mut Buffer) -> IoResult<Self> {
let limbs = src.read_target_vec()?;
Ok(Self {
limbs: limbs.into_iter().map(|l| U32Target(l)).collect(),
})
}
}

pub trait CircuitBuilderBiguint<F: RichField + Extendable<D>, const D: usize> {
Expand Down Expand Up @@ -342,6 +353,31 @@ impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F>
out_buffer.set_biguint_target(&self.div, &div);
out_buffer.set_biguint_target(&self.rem, &rem);
}

fn id(&self) -> String {
"BigUintDivRemGenerator".to_string()
}

fn serialize(&self, dst: &mut Vec<u8>) -> IoResult<()> {
self.a.write_to_serializer(dst)?;
self.b.write_to_serializer(dst)?;
self.div.write_to_serializer(dst)?;
self.rem.write_to_serializer(dst)
}

fn deserialize(src: &mut Buffer) -> IoResult<Self> {
let a = BigUintTarget::deserialize(src)?;
let b = BigUintTarget::deserialize(src)?;
let div = BigUintTarget::deserialize(src)?;
let rem = BigUintTarget::deserialize(src)?;
Ok(Self {
a,
b,
div,
rem,
_phantom: PhantomData,
})
}
}

#[cfg(test)]
Expand Down
41 changes: 41 additions & 0 deletions src/gadgets/glv.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use alloc::vec::Vec;
use core::marker::PhantomData;
use alloc::string::{String, ToString};

use plonky2::field::extension::Extendable;
use plonky2::field::secp256k1_base::Secp256K1Base;
Expand All @@ -10,6 +11,7 @@ use plonky2::iop::generator::{GeneratedValues, SimpleGenerator};
use plonky2::iop::target::{BoolTarget, Target};
use plonky2::iop::witness::{PartitionWitness, WitnessWrite};
use plonky2::plonk::circuit_builder::CircuitBuilder;
use plonky2::util::serialization::{IoResult, Buffer, Write, Read};

use crate::curve::glv::{decompose_secp256k1_scalar, GLV_BETA, GLV_S};
use crate::curve::secp256k1::Secp256K1;
Expand All @@ -18,6 +20,8 @@ use crate::gadgets::curve::{AffinePointTarget, CircuitBuilderCurve};
use crate::gadgets::curve_msm::curve_msm_circuit;
use crate::gadgets::nonnative::{CircuitBuilderNonNative, NonNativeTarget};

use super::biguint::BigUintTarget;

pub trait CircuitBuilderGlv<F: RichField + Extendable<D>, const D: usize> {
fn secp256k1_glv_beta(&mut self) -> NonNativeTarget<Secp256K1Base>;

Expand Down Expand Up @@ -128,6 +132,43 @@ impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F>
out_buffer.set_bool_target(self.k1_neg, k1_neg);
out_buffer.set_bool_target(self.k2_neg, k2_neg);
}

fn id(&self) -> String {
"GLVDecompositionGenerator".to_string()
}

fn serialize(&self, dst: &mut Vec<u8>) -> IoResult<()> {
self.k.value.write_to_serializer(dst)?;
self.k1.value.write_to_serializer(dst)?;
self.k2.value.write_to_serializer(dst)?;
dst.write_target_bool(self.k1_neg)?;
dst.write_target_bool(self.k2_neg)
}

fn deserialize(src: &mut Buffer) -> IoResult<Self>{
let k = NonNativeTarget::<Secp256K1Scalar>{
value: BigUintTarget::deserialize(src)?,
_phantom: PhantomData,
};
let k1 = NonNativeTarget::<Secp256K1Scalar>{
value: BigUintTarget::deserialize(src)?,
_phantom: PhantomData,
};
let k2 = NonNativeTarget::<Secp256K1Scalar>{
value: BigUintTarget::deserialize(src)?,
_phantom: PhantomData,
};
let k1_neg = src.read_target_bool()?;
let k2_neg = src.read_target_bool()?;
Ok(GLVDecompositionGenerator{
k,
k1,
k2,
k1_neg,
k2_neg,
_phantom: PhantomData,
})
}
}

#[cfg(test)]
Expand Down
174 changes: 174 additions & 0 deletions src/gadgets/nonnative.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use alloc::vec;
use alloc::vec::Vec;
use core::marker::PhantomData;

use alloc::string::{String, ToString};
use num::{BigUint, Integer, One, Zero};
use plonky2::field::extension::Extendable;
use plonky2::field::types::{Field, PrimeField};
Expand All @@ -15,6 +16,8 @@ use plonky2_u32::gadgets::arithmetic_u32::{CircuitBuilderU32, U32Target};
use plonky2_u32::gadgets::range_check::range_check_u32_circuit;
use plonky2_u32::witness::GeneratedValuesU32;

use plonky2::util::serialization::{IoResult, Buffer, Write, Read};

use crate::gadgets::biguint::{
BigUintTarget, CircuitBuilderBiguint, GeneratedValuesBigUint, WitnessBigUint,
};
Expand Down Expand Up @@ -484,6 +487,41 @@ impl<F: RichField + Extendable<D>, const D: usize, FF: PrimeField> SimpleGenerat
out_buffer.set_biguint_target(&self.sum.value, &sum_reduced);
out_buffer.set_bool_target(self.overflow, overflow);
}

fn id(&self) -> String {
"NonNativeAdditionGenerator".to_string()
}

fn serialize(&self, dst: &mut Vec<u8>) -> IoResult<()> {
self.a.value.write_to_serializer(dst)?;
self.b.value.write_to_serializer(dst)?;
self.sum.value.write_to_serializer(dst)?;
dst.write_target_bool(self.overflow)
}

fn deserialize(src: &mut Buffer) -> IoResult<Self>{
let a = NonNativeTarget {
value: BigUintTarget::deserialize(src)?,
_phantom: PhantomData,
};
let b = NonNativeTarget {
value: BigUintTarget::deserialize(src)?,
_phantom: PhantomData,
};
let sum = NonNativeTarget {
value: BigUintTarget::deserialize(src)?,
_phantom: PhantomData,
};
let overflow = src.read_target_bool()?;

Ok(NonNativeAdditionGenerator {
a,
b,
sum,
overflow,
_phantom: PhantomData,
})
}
}

#[derive(Debug)]
Expand Down Expand Up @@ -529,6 +567,44 @@ impl<F: RichField + Extendable<D>, const D: usize, FF: PrimeField> SimpleGenerat
out_buffer.set_biguint_target(&self.sum.value, &sum_reduced);
out_buffer.set_u32_target(self.overflow, overflow);
}

fn id(&self) -> String {
"NonNativeMultipleAddsGenerator".to_string()
}

fn serialize(&self, dst: &mut Vec<u8>) -> IoResult<()> {
let summands_count = self.summands.len() as u32;
dst.write_u32(summands_count)?;
self.summands
.iter()
.try_for_each(|summand| summand.value.write_to_serializer(dst))?;
self.sum.value.write_to_serializer(dst)?;
dst.write_target(self.overflow.0)
}

fn deserialize(src: &mut Buffer) -> IoResult<Self>{
let summands_count = src.read_u32()?;
let mut summands = Vec::with_capacity(summands_count as usize);
for _ in 0..summands_count {
let summand = NonNativeTarget {
value: BigUintTarget::deserialize(src)?,
_phantom: PhantomData,
};
summands.push(summand);
}
let sum = NonNativeTarget {
value: BigUintTarget::deserialize(src)?,
_phantom: PhantomData,
};
let overflow = src.read_target()?;

Ok(NonNativeMultipleAddsGenerator {
summands,
sum,
overflow: U32Target(overflow),
_phantom: PhantomData,
})
}
}

#[derive(Debug)]
Expand Down Expand Up @@ -570,6 +646,41 @@ impl<F: RichField + Extendable<D>, const D: usize, FF: PrimeField> SimpleGenerat
out_buffer.set_biguint_target(&self.diff.value, &diff_biguint);
out_buffer.set_bool_target(self.overflow, overflow);
}

fn id(&self) -> String {
"NonNativeSubtractionGenerator".to_string()
}

fn serialize(&self, dst: &mut Vec<u8>) -> IoResult<()> {
self.a.value.write_to_serializer(dst)?;
self.b.value.write_to_serializer(dst)?;
self.diff.value.write_to_serializer(dst)?;
dst.write_target_bool(self.overflow)
}

fn deserialize(src: &mut Buffer) -> IoResult<Self> {
let a = NonNativeTarget {
value: BigUintTarget::deserialize(src)?,
_phantom: PhantomData,
};
let b = NonNativeTarget {
value: BigUintTarget::deserialize(src)?,
_phantom: PhantomData,
};
let diff = NonNativeTarget {
value: BigUintTarget::deserialize(src)?,
_phantom: PhantomData,
};
let overflow = src.read_target_bool()?;

Ok(NonNativeSubtractionGenerator {
a,
b,
diff,
overflow,
_phantom: PhantomData,
})
}
}

#[derive(Debug)]
Expand Down Expand Up @@ -609,6 +720,41 @@ impl<F: RichField + Extendable<D>, const D: usize, FF: PrimeField> SimpleGenerat
out_buffer.set_biguint_target(&self.prod.value, &prod_reduced);
out_buffer.set_biguint_target(&self.overflow, &overflow_biguint);
}

fn id(&self) -> String {
"NonNativeMultiplicationGenerator".to_string()
}

fn serialize(&self, dst: &mut Vec<u8>) -> IoResult<()> {
self.a.value.write_to_serializer(dst)?;
self.b.value.write_to_serializer(dst)?;
self.prod.value.write_to_serializer(dst)?;
self.overflow.write_to_serializer(dst)
}

fn deserialize(src: &mut Buffer) -> IoResult<Self>{
let a = NonNativeTarget {
value: BigUintTarget::deserialize(src)?,
_phantom: PhantomData,
};
let b = NonNativeTarget {
value: BigUintTarget::deserialize(src)?,
_phantom: PhantomData,
};
let prod = NonNativeTarget {
value: BigUintTarget::deserialize(src)?,
_phantom: PhantomData,
};
let overflow = BigUintTarget::deserialize(src)?;

Ok(NonNativeMultiplicationGenerator {
a,
b,
prod,
overflow,
_phantom: PhantomData,
})
}
}

#[derive(Debug)]
Expand Down Expand Up @@ -639,6 +785,34 @@ impl<F: RichField + Extendable<D>, const D: usize, FF: PrimeField> SimpleGenerat
out_buffer.set_biguint_target(&self.div, &div);
out_buffer.set_biguint_target(&self.inv, &inv_biguint);
}

fn id(&self) -> String {
"NonNativeInverseGenerator".to_string()
}

fn serialize(&self, dst: &mut Vec<u8>) -> IoResult<()> {
self.x.value.write_to_serializer(dst)?;
self.inv.write_to_serializer(dst)?;
self.div.write_to_serializer(dst)

}

fn deserialize(src: &mut Buffer) -> IoResult<Self>{
let x = NonNativeTarget {
value: BigUintTarget::deserialize(src)?,
_phantom: PhantomData,
};
let inv = BigUintTarget::deserialize(src)?;
let div = BigUintTarget::deserialize(src)?;

Ok(NonNativeInverseGenerator {
x,
inv,
div,
_phantom: PhantomData,
})
}

}

#[cfg(test)]
Expand Down