|
|
@ -32,61 +32,6 @@ use crate::schnorr::{SchnorrPublicKey, SchnorrSignature}; |
|
|
|
|
|
|
|
type GoldF = GoldilocksField;
|
|
|
|
|
|
|
|
pub struct MessageTarget {
|
|
|
|
msg: Vec<Target>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl MessageTarget {
|
|
|
|
fn new_with_size(builder: &mut CircuitBuilder<GoldF, 2>, n: usize) -> Self {
|
|
|
|
Self {
|
|
|
|
msg: builder.add_virtual_targets(n),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn set_witness(&self, pw: &mut PartialWitness<GoldF>, msg: &Vec<GoldF>) -> Result<()> {
|
|
|
|
assert!(msg.len() == self.msg.len());
|
|
|
|
for (&t, &x) in self.msg.iter().zip(msg.iter()) {
|
|
|
|
pw.set_target(t, x)?;
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct SchnorrSignatureTarget {
|
|
|
|
s: Target,
|
|
|
|
e: Target,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl SchnorrSignatureTarget {
|
|
|
|
fn new_virtual(builder: &mut CircuitBuilder<GoldF, 2>) -> Self {
|
|
|
|
let s = builder.add_virtual_target();
|
|
|
|
let e = builder.add_virtual_target();
|
|
|
|
Self{ s, e }
|
|
|
|
}
|
|
|
|
|
|
|
|
fn set_witness(&self, pw: &mut PartialWitness<GoldF>, sig: &SchnorrSignature) -> Result<()> {
|
|
|
|
pw.set_target(self.s, GoldilocksField::from_canonical_u64(sig.s))?;
|
|
|
|
pw.set_target(self.e, GoldilocksField::from_canonical_u64(sig.e))?;
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct SchnorrPublicKeyTarget {
|
|
|
|
pk: Target,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl SchnorrPublicKeyTarget {
|
|
|
|
fn new_virtual(builder: &mut CircuitBuilder<GoldF, 2>) -> Self {
|
|
|
|
Self{ pk: builder.add_virtual_target() }
|
|
|
|
}
|
|
|
|
|
|
|
|
fn set_witness(&self, pw: &mut PartialWitness<GoldF>, pk: &SchnorrPublicKey) -> Result<()> {
|
|
|
|
pw.set_target(self.pk, pk.pk)?;
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, Default)]
|
|
|
|
pub struct Mod65537Generator {
|
|
|
|
a: Target,
|
|
|
@ -119,7 +64,6 @@ impl SimpleGenerator for Mod65537Generator { |
|
|
|
}
|
|
|
|
|
|
|
|
fn serialize(&self, dst: &mut Vec<u8>, common_data: &CommonCircuitData<GoldF, 2>) -> IoResult<()> {
|
|
|
|
println!("SERIALIZATION! What is this good for?");
|
|
|
|
dst.write_target(self.a)?;
|
|
|
|
dst.write_target(self.q)?;
|
|
|
|
dst.write_target(self.r)?;
|
|
|
@ -130,7 +74,6 @@ impl SimpleGenerator for Mod65537Generator { |
|
|
|
where
|
|
|
|
Self: Sized |
|
|
|
{
|
|
|
|
println!("DESERIALIZATION! What is this good for?");
|
|
|
|
let a = src.read_target()?;
|
|
|
|
let q = src.read_target()?;
|
|
|
|
let r = src.read_target()?;
|
|
|
@ -138,23 +81,21 @@ impl SimpleGenerator for Mod65537Generator { |
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct SchnorrBuilder {}
|
|
|
|
pub struct Mod65537Builder {}
|
|
|
|
|
|
|
|
impl SchnorrBuilder {
|
|
|
|
impl Mod65537Builder {
|
|
|
|
// Reduce a modulo the constant 65537
|
|
|
|
// where a is the canonical representative for an element of the field
|
|
|
|
// (meaning: 0 \leq a < p)
|
|
|
|
|
|
|
|
// To verify this, write
|
|
|
|
// To prove this, write
|
|
|
|
// a = 65537 * q + r, and do range checks to check that:
|
|
|
|
// 0 <= q <= floor(p / 65537)
|
|
|
|
// 0 <= r < 65537
|
|
|
|
// (these first two checks guarantee that a lies in the range [0, p + 65536])
|
|
|
|
// if q = floor(p / 65537) then r = 0
|
|
|
|
// (note that p % 65537 == 1 so this is the only possibility)
|
|
|
|
pub(crate) fn mod_65537 <
|
|
|
|
//C: GenericConfig<2, F = GoldF>,
|
|
|
|
> (
|
|
|
|
pub(crate) fn mod_65537 (
|
|
|
|
builder: &mut CircuitBuilder::<GoldF, 2>,
|
|
|
|
a: Target,
|
|
|
|
) -> Target {
|
|
|
@ -194,6 +135,67 @@ impl SchnorrBuilder { |
|
|
|
|
|
|
|
r
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct MessageTarget {
|
|
|
|
msg: Vec<Target>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl MessageTarget {
|
|
|
|
fn new_with_size(builder: &mut CircuitBuilder<GoldF, 2>, n: usize) -> Self {
|
|
|
|
Self {
|
|
|
|
msg: builder.add_virtual_targets(n),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn set_witness(&self, pw: &mut PartialWitness<GoldF>, msg: &Vec<GoldF>) -> Result<()> {
|
|
|
|
assert!(msg.len() == self.msg.len());
|
|
|
|
for (&t, &x) in self.msg.iter().zip(msg.iter()) {
|
|
|
|
pw.set_target(t, x)?;
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct SchnorrSignatureTarget {
|
|
|
|
s: Target,
|
|
|
|
e: Target,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl SchnorrSignatureTarget {
|
|
|
|
fn new_virtual(builder: &mut CircuitBuilder<GoldF, 2>) -> Self {
|
|
|
|
let s = builder.add_virtual_target();
|
|
|
|
let e = builder.add_virtual_target();
|
|
|
|
Self{ s, e }
|
|
|
|
}
|
|
|
|
|
|
|
|
fn set_witness(&self, pw: &mut PartialWitness<GoldF>, sig: &SchnorrSignature) -> Result<()> {
|
|
|
|
pw.set_target(self.s, GoldilocksField::from_canonical_u64(sig.s))?;
|
|
|
|
pw.set_target(self.e, GoldilocksField::from_canonical_u64(sig.e))?;
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct SchnorrPublicKeyTarget {
|
|
|
|
pk: Target,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl SchnorrPublicKeyTarget {
|
|
|
|
fn new_virtual(builder: &mut CircuitBuilder<GoldF, 2>) -> Self {
|
|
|
|
Self{ pk: builder.add_virtual_target() }
|
|
|
|
}
|
|
|
|
|
|
|
|
fn set_witness(&self, pw: &mut PartialWitness<GoldF>, pk: &SchnorrPublicKey) -> Result<()> {
|
|
|
|
pw.set_target(self.pk, pk.pk)?;
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct SchnorrBuilder {}
|
|
|
|
|
|
|
|
impl SchnorrBuilder {
|
|
|
|
|
|
|
|
|
|
|
|
pub fn constrain_sig <
|
|
|
|
C: GenericConfig<2, F = GoldF>,
|
|
|
@ -204,13 +206,12 @@ impl SchnorrBuilder { |
|
|
|
msg: &MessageTarget,
|
|
|
|
pk: &SchnorrPublicKeyTarget,
|
|
|
|
) -> () {
|
|
|
|
println!("WARNING constrain_sig() is not done yet DONT USE IT");
|
|
|
|
|
|
|
|
let PRIME_GROUP_GEN: Target = builder.constant(GoldF::from_canonical_u64(6612579038192137166));
|
|
|
|
let PRIME_GROUP_ORDER: Target = builder.constant(GoldF::from_canonical_u64(65537));
|
|
|
|
const num_bits_exp: usize = 32;
|
|
|
|
|
|
|
|
/*
|
|
|
|
/* here's the direct verification calculation,
|
|
|
|
which we verify in-circuit
|
|
|
|
let r: GoldF = Self::pow(self.PRIME_GROUP_GEN, sig.s)
|
|
|
|
* Self::pow(pk.pk, sig.e);
|
|
|
|
let e_v: u64 = self.hash_insecure(&r, msg);
|
|
|
@ -229,7 +230,7 @@ impl SchnorrBuilder { |
|
|
|
hash_input,
|
|
|
|
).elements[0]; // whoops have to take mod group order;
|
|
|
|
|
|
|
|
let e: Target = Self::mod_65537(builder, hash_output);
|
|
|
|
let e: Target = Mod65537Builder::mod_65537(builder, hash_output);
|
|
|
|
|
|
|
|
// enforce equality
|
|
|
|
builder.connect(e, sig.e);
|
|
|
@ -239,7 +240,7 @@ impl SchnorrBuilder { |
|
|
|
#[cfg(test)]
|
|
|
|
mod tests{
|
|
|
|
use crate::schnorr::{SchnorrPublicKey, SchnorrSecretKey, SchnorrSigner, SchnorrSignature};
|
|
|
|
use crate::schnorr_prover::{MessageTarget, SchnorrBuilder, SchnorrPublicKeyTarget, SchnorrSignatureTarget};
|
|
|
|
use crate::schnorr_prover::{MessageTarget, Mod65537Builder, SchnorrBuilder, SchnorrPublicKeyTarget, SchnorrSignatureTarget};
|
|
|
|
use plonky2::hash::poseidon::Poseidon;
|
|
|
|
use plonky2::iop::{
|
|
|
|
target::Target,
|
|
|
@ -280,7 +281,7 @@ mod tests{ |
|
|
|
.collect();
|
|
|
|
|
|
|
|
let r: Vec<Target> = a.iter()
|
|
|
|
.map(|targ| SchnorrBuilder::mod_65537(&mut builder, *targ))
|
|
|
|
.map(|targ| Mod65537Builder::mod_65537(&mut builder, *targ))
|
|
|
|
.collect();
|
|
|
|
|
|
|
|
// check that the outputs are correct,
|
|
|
@ -290,7 +291,6 @@ mod tests{ |
|
|
|
let r_expected: Vec<Target> = r_expected64.iter()
|
|
|
|
.map(|x| builder.constant(GoldilocksField::from_canonical_u64(*x)))
|
|
|
|
.collect();
|
|
|
|
|
|
|
|
r.iter().zip(r_expected.iter())
|
|
|
|
.for_each(|(x, y)| builder.connect(*x, *y));
|
|
|
|
|
|
|
|