arnaucube
arnaucube/schnorrPublic Self-hosted repository
schnorr/src/main.rs
src/main.rsRaw
  1use plonky2::hash::poseidon::PoseidonHash;
  2use plonky2::field::goldilocks_field::GoldilocksField;
  3use plonky2::field::types::Field;
  4use plonky2::plonk::config::Hasher;
  5use plonky2::field::types::PrimeField64;
  6use rand;
  7use rand::Rng;
  8
  9const BIG_GROUP_GEN: GoldilocksField = GoldilocksField(14293326489335486720);
 10
 11struct SchnorrSigner {
 12    PRIME_GROUP_GEN: GoldilocksField,
 13    PRIME_GROUP_ORDER: u64,
 14}
 15
 16struct SchnorrSecretKey {
 17    sk: u64,
 18}
 19
 20struct SchnorrPublicKey {
 21    pk: GoldilocksField,
 22}
 23
 24struct SchnorrSignature {
 25    s: u64,
 26    e: u64,
 27}
 28
 29impl SchnorrSigner{
 30    fn new() -> Self {
 31        let quotient_order: u64 = (1 << 48) - (1 << 32);
 32        let PRIME_GROUP_GEN: GoldilocksField = Self::pow(BIG_GROUP_GEN, quotient_order);
 33        let PRIME_GROUP_ORDER: u64 = (1 << 32) + 1;
 34        SchnorrSigner{PRIME_GROUP_GEN, PRIME_GROUP_ORDER}
 35    }
 36
 37    fn pow(x: GoldilocksField, a: u64) -> GoldilocksField {
 38        let mut a_copy = a;
 39        let mut res = GoldilocksField(1);
 40        let mut x_pow_2n = x.clone();
 41        while (a_copy > 0) {
 42            if (a_copy % 2 != 0) {
 43                res *= x_pow_2n;
 44            }
 45            a_copy /= 2;
 46            x_pow_2n *= x_pow_2n;
 47        }
 48        res
 49    }
 50
 51    fn keygen(&self, sk: SchnorrSecretKey) -> SchnorrPublicKey {
 52        let pk: GoldilocksField = Self::pow(self.PRIME_GROUP_GEN, sk.sk);
 53        SchnorrPublicKey{pk: pk}
 54    }
 55
 56    fn hash_insecure(&self, r: &GoldilocksField, msg: &Vec<GoldilocksField>) -> u64 {
 57        let poseidon_input: Vec<GoldilocksField> = std::iter::once(r)
 58            .chain(msg.iter())
 59            .copied()
 60            .collect();
 61
 62        println!("Running hash on concatenated elts: {:?}", poseidon_input);
 63        let h = PoseidonHash::hash_no_pad(&poseidon_input);
 64        h.elements[0].to_canonical_u64() % self.PRIME_GROUP_ORDER
 65    }
 66
 67    fn rand_group_multiplier(&self, rng: &mut rand::rngs::ThreadRng) -> u64 {
 68        let group_order: u64 = (1 << 16) + 1;
 69        rng.gen_range(0..group_order)
 70    }
 71
 72    fn sign(&self, msg: &Vec<GoldilocksField>, sk: SchnorrSecretKey, rng: &mut rand::rngs::ThreadRng) -> SchnorrSignature {
 73        let k: u64 = self.rand_group_multiplier(rng);
 74        let r: GoldilocksField = Self::pow(self.PRIME_GROUP_GEN, k);
 75        let e: u64 = self.hash_insecure(&r, msg);
 76        assert!(k < self.PRIME_GROUP_ORDER);
 77        assert!(sk < self.PRIME_GROUP_ORDER);
 78        assert!(e < self.PRIME_GROUP_ORDER);
 79        let mut s128: u128 = ((k as u128) + (sk.sk as u128) * (e as u128));
 80        s128 %= (self.PRIME_GROUP_ORDER as u128);
 81        let s: u64 = s128 as u64;
 82        SchnorrSignature{e, s}
 83    }
 84
 85    fn verify(&self, sig: SchnorrSignature, msg: &Vec<GoldilocksField>, pk: SchnorrPublicKey) -> bool {
 86        let r: GoldilocksField = Self::pow(self.PRIME_GROUP_GEN, sig.s)
 87            * Self::pow(pk.pk, sig.e);
 88        let e_v: u64 = self.hash_insecure(&r, msg);
 89        e_v == sig.e
 90    }
 91}
 92
 93fn main() {
 94    println!("Hello, world!");
 95
 96    let mut rng: rand::rngs::ThreadRng = rand::thread_rng();
 97
 98    type F = GoldilocksField;
 99
100    let x = F::from_noncanonical_i64(3);
101    let h = PoseidonHash::hash_no_pad(&[x]);
102    println!("Hash is {:?}", h);
103}
104
105#[cfg(test)]
106mod tests {
107    use plonky2::field::goldilocks_field::GoldilocksField;
108
109    use crate::SchnorrSigner;
110
111    #[test]
112    fn test_pow() {
113        let g = GoldilocksField(3);
114        let res = GoldilocksField(16305451354880172407);
115        assert_eq!(res, SchnorrSigner::pow(g, 1234567));
116    }
117
118    #[test]
119    fn test_sig() {
120        println!("NOT IMPLEMENTED");
121    }
122}