mirror of
https://github.com/arnaucube/schnorr.git
synced 2026-01-12 17:01:29 +01:00
Clean up code, still works
This commit is contained in:
@@ -55,7 +55,6 @@ impl SchnorrSigner{
|
||||
|
||||
pub fn keygen(&self, sk: &SchnorrSecretKey) -> SchnorrPublicKey {
|
||||
let pk: GoldilocksField = Self::pow(self.PRIME_GROUP_GEN, sk.sk).inverse();
|
||||
println!("{:?}", self.PRIME_GROUP_GEN);
|
||||
// self.PRIME_GROUP_GEN is 6612579038192137166
|
||||
SchnorrPublicKey{pk: pk}
|
||||
}
|
||||
@@ -66,7 +65,6 @@ impl SchnorrSigner{
|
||||
.copied()
|
||||
.collect();
|
||||
|
||||
println!("Running hash on concatenated elts: {:?}", poseidon_input);
|
||||
let h = PoseidonHash::hash_no_pad(&poseidon_input);
|
||||
h.elements[0].to_canonical_u64() % self.PRIME_GROUP_ORDER
|
||||
}
|
||||
@@ -89,9 +87,6 @@ impl SchnorrSigner{
|
||||
assert!(k < self.PRIME_GROUP_ORDER);
|
||||
assert!(sk.sk < self.PRIME_GROUP_ORDER);
|
||||
assert!(e < self.PRIME_GROUP_ORDER);
|
||||
//println!("Super secret k: {:?}", k);
|
||||
//println!("Super secret r: {:?}", r);
|
||||
//println!("PRIME_GROUP_ORDER: {:?}", self.PRIME_GROUP_ORDER);
|
||||
let mut s128: u128 = ((k as u128) + (sk.sk as u128) * (e as u128));
|
||||
s128 %= self.PRIME_GROUP_ORDER as u128;
|
||||
let s: u64 = s128 as u64;
|
||||
|
||||
@@ -32,6 +32,111 @@ use crate::schnorr::{SchnorrPublicKey, SchnorrSignature};
|
||||
|
||||
type GoldF = GoldilocksField;
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Mod65537Generator {
|
||||
a: Target,
|
||||
q: Target,
|
||||
r: Target,
|
||||
}
|
||||
|
||||
impl SimpleGenerator<GoldF, 2> for Mod65537Generator {
|
||||
fn id(&self) -> String {
|
||||
"Mod65537Generator".to_string()
|
||||
}
|
||||
fn dependencies(&self) -> Vec<Target> {
|
||||
vec![self.a]
|
||||
}
|
||||
|
||||
fn run_once(
|
||||
&self,
|
||||
witness: &PartitionWitness<GoldF>,
|
||||
out_buffer: &mut GeneratedValues<GoldF>,
|
||||
) -> Result<()> {
|
||||
let a = witness.get_target(self.a);
|
||||
let a64 = a.to_canonical_u64();
|
||||
let q64 = a64 / 65537;
|
||||
let r64 = a64 % 65537;
|
||||
|
||||
out_buffer.set_target(self.q, GoldF::from_canonical_u64(q64));
|
||||
out_buffer.set_target(self.r, GoldF::from_canonical_u64(r64));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn serialize(&self, dst: &mut Vec<u8>, common_data: &CommonCircuitData<GoldF, 2>) -> IoResult<()> {
|
||||
dst.write_target(self.a)?;
|
||||
dst.write_target(self.q)?;
|
||||
dst.write_target(self.r)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn deserialize(src: &mut Buffer, common_data: &CommonCircuitData<GoldF, 2>) -> IoResult<Self>
|
||||
where
|
||||
Self: Sized
|
||||
{
|
||||
let a = src.read_target()?;
|
||||
let q = src.read_target()?;
|
||||
let r = src.read_target()?;
|
||||
Ok(Self { a, q, r })
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Mod65537Builder {}
|
||||
|
||||
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 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 (
|
||||
builder: &mut CircuitBuilder::<GoldF, 2>,
|
||||
a: Target,
|
||||
) -> Target {
|
||||
let q = builder.add_virtual_target();
|
||||
let r = builder.add_virtual_target();
|
||||
|
||||
// the Mod65537Generator will assign values to q and r later
|
||||
builder.add_simple_generator( Mod65537Generator { a, q, r } );
|
||||
|
||||
// impose four constraints
|
||||
// 1. a = 65537 * q + r
|
||||
let t65537 = builder.constant(GoldF::from_canonical_u64(65537));
|
||||
let a_copy = builder.mul_add(t65537, q, r);
|
||||
builder.connect(a, a_copy);
|
||||
|
||||
// 2. 0 <= q <= floor(p / 65537)
|
||||
// max_q is 281470681743360 = floor(p / 65537) = (p-1) / 65537 = 2^48 - 2^32
|
||||
let max_q = builder.constant(GoldF::from_canonical_u64(281470681743360));
|
||||
builder.range_check(q, 48);
|
||||
let diff_q = builder.sub(max_q, q);
|
||||
builder.range_check(diff_q, 48);
|
||||
|
||||
// 3. 0 <= r < 65537
|
||||
let max_r = builder.constant(GoldF::from_canonical_u64(65537));
|
||||
builder.range_check(r, 17);
|
||||
let diff_r = builder.sub(max_r, r);
|
||||
builder.range_check(diff_r, 17);
|
||||
|
||||
// 4. if q = floor(p / 65537) then r = 0
|
||||
let q_equals_max = builder.is_equal(q, max_q);
|
||||
let prod_temp = builder.mul(q_equals_max.target, r);
|
||||
let zero_temp = builder.zero();
|
||||
builder.connect(prod_temp, zero_temp);
|
||||
|
||||
// throw in the Generator to tell builder how to compute r
|
||||
builder.add_simple_generator( Mod65537Generator {a, q, r} );
|
||||
|
||||
r
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MessageTarget {
|
||||
msg: Vec<Target>,
|
||||
}
|
||||
@@ -87,113 +192,10 @@ impl SchnorrPublicKeyTarget {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Mod65537Generator {
|
||||
a: Target,
|
||||
q: Target,
|
||||
r: Target,
|
||||
}
|
||||
|
||||
impl SimpleGenerator<GoldF, 2> for Mod65537Generator {
|
||||
fn id(&self) -> String {
|
||||
"Mod65537Generator".to_string()
|
||||
}
|
||||
fn dependencies(&self) -> Vec<Target> {
|
||||
vec![self.a]
|
||||
}
|
||||
|
||||
fn run_once(
|
||||
&self,
|
||||
witness: &PartitionWitness<GoldF>,
|
||||
out_buffer: &mut GeneratedValues<GoldF>,
|
||||
) -> Result<()> {
|
||||
let a = witness.get_target(self.a);
|
||||
let a64 = a.to_canonical_u64();
|
||||
let q64 = a64 / 65537;
|
||||
let r64 = a64 % 65537;
|
||||
|
||||
out_buffer.set_target(self.q, GoldF::from_canonical_u64(q64));
|
||||
out_buffer.set_target(self.r, GoldF::from_canonical_u64(r64));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
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)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn deserialize(src: &mut Buffer, common_data: &CommonCircuitData<GoldF, 2>) -> IoResult<Self>
|
||||
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()?;
|
||||
Ok(Self { a, q, r })
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SchnorrBuilder {}
|
||||
|
||||
impl SchnorrBuilder {
|
||||
// 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
|
||||
// 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>,
|
||||
> (
|
||||
builder: &mut CircuitBuilder::<GoldF, 2>,
|
||||
a: Target,
|
||||
) -> Target {
|
||||
let q = builder.add_virtual_target();
|
||||
let r = builder.add_virtual_target();
|
||||
|
||||
// the Mod65537Generator will assign values to q and r later
|
||||
builder.add_simple_generator( Mod65537Generator { a, q, r } );
|
||||
|
||||
// impose four constraints
|
||||
// 1. a = 65537 * q + r
|
||||
let t65537 = builder.constant(GoldF::from_canonical_u64(65537));
|
||||
let a_copy = builder.mul_add(t65537, q, r);
|
||||
builder.connect(a, a_copy);
|
||||
|
||||
// 2. 0 <= q <= floor(p / 65537)
|
||||
// max_q is 281470681743360 = floor(p / 65537) = (p-1) / 65537 = 2^48 - 2^32
|
||||
let max_q = builder.constant(GoldF::from_canonical_u64(281470681743360));
|
||||
builder.range_check(q, 48);
|
||||
let diff_q = builder.sub(max_q, q);
|
||||
builder.range_check(diff_q, 48);
|
||||
|
||||
// 3. 0 <= r < 65537
|
||||
let max_r = builder.constant(GoldF::from_canonical_u64(65537));
|
||||
builder.range_check(r, 17);
|
||||
let diff_r = builder.sub(max_r, r);
|
||||
builder.range_check(diff_r, 17);
|
||||
|
||||
// 4. if q = floor(p / 65537) then r = 0
|
||||
let q_equals_max = builder.is_equal(q, max_q);
|
||||
let prod_temp = builder.mul(q_equals_max.target, r);
|
||||
let zero_temp = builder.zero();
|
||||
builder.connect(prod_temp, zero_temp);
|
||||
|
||||
// throw in the Generator to tell builder how to compute r
|
||||
builder.add_simple_generator( Mod65537Generator {a, q, r} );
|
||||
|
||||
r
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user