aboutsummaryrefslogtreecommitdiff
path: root/guests/eddsa_poseidon/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'guests/eddsa_poseidon/src/lib.rs')
-rw-r--r--guests/eddsa_poseidon/src/lib.rs65
1 files changed, 65 insertions, 0 deletions
diff --git a/guests/eddsa_poseidon/src/lib.rs b/guests/eddsa_poseidon/src/lib.rs
new file mode 100644
index 0000000..53df361
--- /dev/null
+++ b/guests/eddsa_poseidon/src/lib.rs
@@ -0,0 +1,65 @@
+#![cfg_attr(feature = "no_std", no_std)]
+
+use std::default::Default;
+use std::hash::Hasher;
+use std::hash::poseidon::PoseidonHasher;
+
+mod ec;
+use ec::{ baby_jubjub, TEPoint, Field };
+
+#[guests_macro::proving_entrypoint]
+pub fn main(
+ msg: Field,
+ pub_key_x: Field,
+ pub_key_y: Field,
+ r8_x: Field,
+ r8_y: Field,
+ s: Field,
+) -> bool {
+ eddsa_verify::<PoseidonHasher>(pub_key_x, pub_key_y, s, r8_x, r8_y, msg)
+}
+
+pub fn eddsa_verify<H>(
+ pub_key_x: Field,
+ pub_key_y: Field,
+ signature_s: Field,
+ signature_r8_x: Field,
+ signature_r8_y: Field,
+ message: Field,
+) -> bool
+where
+ H: Hasher + Default,
+{
+ // Verifies by testing:
+ // S * B8 = R8 + H(R8, A, m) * A8
+ let bjj = baby_jubjub();
+
+ let pub_key = TEPoint::new(pub_key_x, pub_key_y);
+ assert!(bjj.curve.contains(pub_key));
+
+ let signature_r8 = TEPoint::new(signature_r8_x, signature_r8_y);
+ assert!(bjj.curve.contains(signature_r8));
+ // Ensure S < Subgroup Order
+ assert!(signature_s.lt(&bjj.suborder));
+ // Calculate the h = H(R, A, msg)
+ let mut hasher = H::default();
+ hasher.write(signature_r8_x);
+ hasher.write(signature_r8_y);
+ hasher.write(pub_key_x);
+ hasher.write(pub_key_y);
+ hasher.write(message);
+ let hash: Field = hasher.finish().into();
+ // Calculate second part of the right side: right2 = h*8*A
+ // Multiply by 8 by doubling 3 times. This also ensures that the result is in the subgroup.
+ let pub_key_mul_2 = bjj.curve.add(pub_key, pub_key);
+ let pub_key_mul_4 = bjj.curve.add(pub_key_mul_2, pub_key_mul_2);
+ let pub_key_mul_8 = bjj.curve.add(pub_key_mul_4, pub_key_mul_4);
+ // We check that A8 is not zero.
+ assert!(!pub_key_mul_8.is_zero());
+ // Compute the right side: R8 + h * A8
+ let right = bjj.curve.add(signature_r8, bjj.curve.mul(hash, pub_key_mul_8));
+ // Calculate left side of equation left = S * B8
+ let left = bjj.curve.mul(signature_s, bjj.base8);
+
+ left.eq(&right)
+}