arnaucube
arnaucube/schnorrPublic Self-hosted repository
Clean up code, still works
Brian Lawrence tideofwords@gmail.com
Mon, 30 Sep 2024 15:18:48 -0700
commit

e8aaa3232254b75a56ca4dbd6bbec84fea9ec8d1

parent

be2eec8b9c82860cf2c750c3947ae90830ba33fc

2 files changed, 70 insertions(+), 75 deletions(-)

jump to
M src/schnorr.rs → src/schnorr.rs

@@ -55,7 +55,6 @@ }

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 @@ .chain(msg.iter())

.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 @@ let e: u64 = self.hash_insecure(&r, msg);

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;
M src/schnorr_prover.rs → src/schnorr_prover.rs

@@ -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 @@ 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)?;

@@ -130,7 +74,6 @@ 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()?;

@@ -138,23 +81,21 @@ Ok(Self { a, q, r })

} } -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 @@ builder.add_simple_generator( Mod65537Generator {a, q, r} );

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 @@ sig: &SchnorrSignatureTarget,

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 @@ let hash_output: Target = builder.hash_n_to_hash_no_pad::<PoseidonHash>(

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 @@

#[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 @@ .map(|x| builder.constant(GoldilocksField::from_canonical_u64(*x)))

.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 @@ println!("Expected residues mod 64: {:?}", r_expected64);

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));