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}