feat(backend): Use Schnorr signatures for signed PODs (#236)

* Implement non-native extension field arithmetic

* Schnorr signature verification (#221)

* Use Schnorr signatures for signed PODs

* add custom gates (#237)

* Clippy

* Formatting

* Apply suggestions from code review

Co-authored-by: Eduard S. <eduardsanou@posteo.net>

* Fix typo

* Fix tests

* Point -> PublicKey

* Remove default nnf_div implementation for clarity

* Code review & edits for clarity

* Remove suspicious mutation

* Simplify computation

* Fix division

* Fix

* Update src/backends/plonky2/primitives/ec/curve.rs

Co-authored-by: Eduard S. <eduardsanou@posteo.net>

* Update src/backends/plonky2/primitives/ec/curve.rs

Co-authored-by: Eduard S. <eduardsanou@posteo.net>

* Fixes

* Add public key to signed POD struct

* Style

* Elaborate on in-circuit field->biguint conversion

* Add missing gates

* Comments

* Add bits to biguint struct

* Comments

* Comment

---------

Co-authored-by: Daniel Gulotta <dgulotta@alum.mit.edu>
Co-authored-by: Eduard S. <eduardsanou@posteo.net>
This commit is contained in:
Ahmad Afuni 2025-06-10 00:24:16 +10:00 committed by GitHub
parent 541c264586
commit c66506c048
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
22 changed files with 2995 additions and 456 deletions

View file

@ -15,14 +15,12 @@ pub use statement::*;
use crate::{
backends::plonky2::{
basetypes::{Proof, ProofWithPublicInputs, VerifierOnlyCircuitData, D},
circuits::mainpod::{
CustomPredicateVerification, MainPodVerifyInput, MainPodVerifyTarget, NUM_PUBLIC_INPUTS,
},
circuits::mainpod::{CustomPredicateVerification, MainPodVerifyInput, MainPodVerifyTarget},
emptypod::EmptyPod,
error::{Error, Result},
mock::emptypod::MockEmptyPod,
primitives::merkletree::MerkleClaimAndProof,
recursion::{self, RecursiveCircuit, RecursiveParams},
recursion::{RecursiveCircuit, RecursiveParams},
signedpod::SignedPod,
STANDARD_REC_MAIN_POD_CIRCUIT_DATA,
},
@ -550,12 +548,14 @@ pub struct MainPod {
fn get_common_data(params: &Params) -> Result<CommonCircuitData<F, D>, Error> {
// TODO: Cache this somehow
// https://github.com/0xPARC/pod2/issues/247
let rec_params = recursion::new_params::<MainPodVerifyTarget>(
params.max_input_recursive_pods,
NUM_PUBLIC_INPUTS,
params,
)?;
Ok(rec_params.common_data().clone())
let rec_circuit_data = &*STANDARD_REC_MAIN_POD_CIRCUIT_DATA;
let (_, circuit_data) =
RecursiveCircuit::<MainPodVerifyTarget>::target_and_circuit_data_padded(
params.max_input_recursive_pods,
&rec_circuit_data.common,
params,
)?;
Ok(circuit_data.common.clone())
}
impl MainPod {
@ -682,11 +682,13 @@ impl RecursivePod for MainPod {
#[cfg(test)]
pub mod tests {
use num::{BigUint, One};
use super::*;
use crate::{
backends::plonky2::{
mock::mainpod::{MockMainPod, MockProver},
primitives::signature::SecretKey,
primitives::ec::schnorr::SecretKey,
signedpod::Signer,
},
examples::{
@ -698,7 +700,7 @@ pub mod tests {
{self},
},
middleware,
middleware::{CustomPredicateRef, NativePredicate as NP, RawValue},
middleware::{CustomPredicateRef, NativePredicate as NP},
op,
};
@ -716,11 +718,11 @@ pub mod tests {
let (gov_id_builder, pay_stub_builder, sanction_list_builder) =
zu_kyc_sign_pod_builders(&params);
let mut signer = Signer(SecretKey(RawValue::from(1)));
let mut signer = Signer(SecretKey(BigUint::one()));
let gov_id_pod = gov_id_builder.sign(&mut signer)?;
let mut signer = Signer(SecretKey(RawValue::from(2)));
let mut signer = Signer(SecretKey(2u64.into()));
let pay_stub_pod = pay_stub_builder.sign(&mut signer)?;
let mut signer = Signer(SecretKey(RawValue::from(3)));
let mut signer = Signer(SecretKey(3u64.into()));
let sanction_list_pod = sanction_list_builder.sign(&mut signer)?;
let kyc_builder =
zu_kyc_pod_builder(&params, &gov_id_pod, &pay_stub_pod, &sanction_list_pod)?;
@ -749,7 +751,7 @@ pub mod tests {
gov_id_builder.insert("idNumber", "4242424242");
gov_id_builder.insert("dateOfBirth", 1169909384);
gov_id_builder.insert("socialSecurityNumber", "G2121210");
let mut signer = Signer(SecretKey(RawValue::from(42)));
let mut signer = Signer(SecretKey(42u64.into()));
let gov_id = gov_id_builder.sign(&mut signer).unwrap();
let now_minus_18y: i64 = 1169909388;
let mut kyc_builder = frontend::MainPodBuilder::new(&params);
@ -831,24 +833,23 @@ pub mod tests {
};
println!("{:#?}", params);
let mut alice = Signer(SecretKey(RawValue::from(1)));
let bob = Signer(SecretKey(RawValue::from(2)));
let mut charlie = Signer(SecretKey(RawValue::from(3)));
let mut alice = Signer(SecretKey(1u32.into()));
let bob = Signer(SecretKey(2u32.into()));
let mut charlie = Signer(SecretKey(3u32.into()));
// Alice attests that she is ETH friends with Charlie and Charlie
// attests that he is ETH friends with Bob.
let alice_attestation =
eth_friend_signed_pod_builder(&params, charlie.public_key().0.into())
.sign(&mut alice)?;
eth_friend_signed_pod_builder(&params, charlie.public_key().into()).sign(&mut alice)?;
let charlie_attestation =
eth_friend_signed_pod_builder(&params, bob.public_key().0.into()).sign(&mut charlie)?;
eth_friend_signed_pod_builder(&params, bob.public_key().into()).sign(&mut charlie)?;
let alice_bob_ethdos_builder = eth_dos_pod_builder(
&params,
false,
&alice_attestation,
&charlie_attestation,
bob.public_key().0.into(),
bob.public_key().into(),
)?;
let mut prover = MockProver {};