Skip to content
This repository has been archived by the owner on Nov 23, 2023. It is now read-only.

Commit

Permalink
fix: eigentrust proof generation and verification (#376)
Browse files Browse the repository at this point in the history
Co-authored-by: duguorong <[email protected]>
  • Loading branch information
brech1 and duguorong009 authored Nov 1, 2023
1 parent 5839805 commit 5799ed4
Show file tree
Hide file tree
Showing 12 changed files with 189 additions and 110 deletions.
13 changes: 12 additions & 1 deletion eigentrust-cli/assets/attestations.csv
Original file line number Diff line number Diff line change
@@ -1,2 +1,13 @@
about,domain,value,message,sig_r,sig_s,rec_id
0x70997970c51812dc3a010c7d01b50e0d17dc79c8,0x0000000000000000000000000000000000000000,5,0x0000000000000000000000000000000000000000000000000000000000000000,0x1cc60bf64279111e233842283422f63cc34235adb4622a905aa325b6c8c44c4f,0xefa0e00156ab25f681075542d005f82e4b53ecdedee9d776268c0d7e7f325a21,1
0x70997970c51812dc3a010c7d01b50e0d17dc79c8,0x0000000000000000000000000000000000000000,10,0x0000000000000000000000000000000000000000000000000000000000000000,0x35d796aa9d85cf941ad74b83bda302eecbb047c5aca245d6d3a793c93b236d29,0x9eba00fad7e20f48374f4ee25aeaf15b16ff8f4a46b484806c09ebb3e6d39c12,1
0x3c44cdddb6a900fa2b585dd299e03d12fa4293bc,0x0000000000000000000000000000000000000000,10,0x0000000000000000000000000000000000000000000000000000000000000000,0x66eb26cda8066652b58b3a7b1c205b264ec9ac779dcdf201937e6ad605cf21ca,0x8915a3f533ce28ba04e893a84acd06c4afb4ed3122f9dfe4fb708ba0919ca04d,0
0x90f79bf6eb2c4f870365e785982e1f101e93b906,0x0000000000000000000000000000000000000000,10,0x0000000000000000000000000000000000000000000000000000000000000000,0x295e449af2d3249dfef036132773fa30e42e276136976914b739db7ccd811920,0x7e6c7df89d201782832591222be9121e7acc9d25c066e9d83e6c9e35e8b21a55,0
0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266,0x0000000000000000000000000000000000000000,10,0x0000000000000000000000000000000000000000000000000000000000000000,0xc953465e18b11946d850504e285d9e942e8f70832ad4868b2862316a362a9253,0x72cbab1a73d5f535bb506185ebd98c6698ec06ddcf1030bc55dc6ae97f4d7109,0
0x3c44cdddb6a900fa2b585dd299e03d12fa4293bc,0x0000000000000000000000000000000000000000,10,0x0000000000000000000000000000000000000000000000000000000000000000,0xbca5ee8a00309bacb4c4e44fa22f7f8195552617be90773ea502b36cdf0ba859,0x1db14610dcc3c4e7a8848f1c9d972a9f7b909872d73f9e14d55e912a2102b607,0
0x90f79bf6eb2c4f870365e785982e1f101e93b906,0x0000000000000000000000000000000000000000,10,0x0000000000000000000000000000000000000000000000000000000000000000,0x2a9c1ddc1fc3dbe26eaf66975aa00af3f7950c4f668aad354fa3f0ab6ec76b5b,0xc825724b91178b39682c0b81bcf787479631221e62b193452e53bd50240c6223,1
0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266,0x0000000000000000000000000000000000000000,10,0x0000000000000000000000000000000000000000000000000000000000000000,0xc3930963d681f6645573912a05286679d43d82f2f32796037c61fbc9083e44b0,0x19e62c5855a24d735cbafec7ae1bf36f68c0c6b2dfda84e3d735c800338fdb25,0
0x70997970c51812dc3a010c7d01b50e0d17dc79c8,0x0000000000000000000000000000000000000000,10,0x0000000000000000000000000000000000000000000000000000000000000000,0xf1d68ea2a6126ff932bf7e675fb798cb88c4837d5e6afcdfbe7e4d7b28d3ad47,0xe3c85704eb9a2b95a126949a41e0cba827668005a3aca9c377ca5f1135f0d34c,0
0x90f79bf6eb2c4f870365e785982e1f101e93b906,0x0000000000000000000000000000000000000000,10,0x0000000000000000000000000000000000000000000000000000000000000000,0x16a137d719ea5c3ab62950d200d1351191a70356cc6ccf3e1b3b8fac9210109f,0xf842bb839d24dabc83f20c8dfb3278ed5b6b49f434fd6b8d8539fccc62073d3f,0
0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266,0x0000000000000000000000000000000000000000,10,0x0000000000000000000000000000000000000000000000000000000000000000,0xabc32b960ec7bc2cb9f38e40f4b3d8aa7a47ca09ca3a2bd2f014ddba121a4b44,0x2b8db4319dbb438f36232d88bd4756cd09248d3aac8314666869d0a0ce63c17b,1
0x70997970c51812dc3a010c7d01b50e0d17dc79c8,0x0000000000000000000000000000000000000000,10,0x0000000000000000000000000000000000000000000000000000000000000000,0x72656c3000dc2fd34a12ba1d4dc0d8cfd4bb7c64fcfb0a00cd6a23e63b39e09a,0xd7155d0c31194651a763faa4ebfdd82be6314b9a5a79d1e001f28b7191d7020e,0
0x3c44cdddb6a900fa2b585dd299e03d12fa4293bc,0x0000000000000000000000000000000000000000,10,0x0000000000000000000000000000000000000000000000000000000000000000,0xec144687ce2ad27e5c170ccab61a20cf608f2119616d22b890c0bbac4c3f25cd,0xf845e319b040368f1febf1ef7efb816f9663f7072ebf592229711c480912ef5a,0
31 changes: 27 additions & 4 deletions eigentrust-cli/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -382,9 +382,20 @@ pub async fn handle_deploy() -> Result<(), EigenError> {
}

/// Handles eigentrust circuit proving key generation.
pub fn handle_et_pk() -> Result<(), EigenError> {
pub async fn handle_et_pk() -> Result<(), EigenError> {
let config = load_config()?;
let mnemonic = load_mnemonic();
let client = Client::new(
mnemonic,
config.chain_id()?,
config.as_address()?,
config.domain()?,
config.node_url,
);
let attestations = load_or_fetch_attestations().await?;
let et_kzg_params = EigenFile::KzgParams(ET_PARAMS_K).load()?;
let proving_key = Client::generate_et_pk(et_kzg_params)?;

let proving_key = client.generate_et_pk(attestations, et_kzg_params)?;

EigenFile::ProvingKey(Circuit::EigenTrust).save(proving_key)
}
Expand Down Expand Up @@ -434,7 +445,13 @@ pub async fn handle_et_verify() -> Result<(), EigenError> {
let proof = EigenFile::Proof(Circuit::EigenTrust).load()?;

// Verify proof
client.verify(kzg_params, public_inputs, proving_key, proof)?;
client.verify(
Circuit::EigenTrust,
kzg_params,
public_inputs,
proving_key,
proof,
)?;

info!("EigenTrust proof has been verified.");
Ok(())
Expand Down Expand Up @@ -601,7 +618,13 @@ pub async fn handle_th_verify() -> Result<(), EigenError> {
let proof = EigenFile::Proof(Circuit::Threshold).load()?;

// Verify proof
client.verify(kzg_params, public_inputs, proving_key, proof)?;
client.verify(
Circuit::Threshold,
kzg_params,
public_inputs,
proving_key,
proof,
)?;

info!("Threshold proof has been verified.");
Ok(())
Expand Down
2 changes: 1 addition & 1 deletion eigentrust-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ async fn main() -> Result<(), EigenError> {
Mode::Bandada(bandada_data) => handle_bandada(bandada_data).await?,
Mode::Deploy => handle_deploy().await?,
Mode::ETProof => handle_et_proof().await?,
Mode::ETProvingKey => handle_et_pk()?,
Mode::ETProvingKey => handle_et_pk().await?,
Mode::ETVerify => handle_et_verify().await?,
Mode::KZGParams(kzg_params_data) => handle_params(kzg_params_data)?,
Mode::LocalScores => handle_scores(AttestationsOrigin::Local).await?,
Expand Down
22 changes: 19 additions & 3 deletions eigentrust-zk/src/circuits/dynamic_sets/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ where
opinion: OpinionConfig<F, H, S>,
}

#[derive(Clone)]
#[derive(Debug, Clone)]
/// Structure of the EigenTrustSet circuit
pub struct EigenTrustSet<
const NUM_NEIGHBOURS: usize,
Expand Down Expand Up @@ -125,7 +125,7 @@ where
/// Constructs a new EigenTrustSet circuit
pub fn new(
attestations: Vec<Vec<Option<SignedAttestation<C, N, NUM_LIMBS, NUM_BITS, P>>>>,
pks: Vec<Option<PublicKey<C, N, NUM_LIMBS, NUM_BITS, P, EC>>>, domain: N,
pks: Vec<Option<PublicKey<C, N, NUM_LIMBS, NUM_BITS, P, EC>>>, _domain: N,
) -> Self {
let mut unassigned_attestations = Vec::new();
let mut unassigned_msg_hashes = Vec::new();
Expand All @@ -137,7 +137,11 @@ where
let mut msg_hashes_row = Vec::new();
let mut s_inv_row = Vec::new();
for j in 0..NUM_NEIGHBOURS {
let att = attestations[i][j].clone().unwrap_or(SignedAttestation::empty(domain));
//
// NOTE: Current circuit impl assumes that the "attestations" are full, even including self-attestation.
// Should be fixed later.
//
let att = attestations[i][j].clone().unwrap();
let unassigned_attestation = UnassignedSignedAttestation::from(att.clone());
let att_hash = att.attestation.hash::<HASHER_WIDTH, HN>();
let msg_hash_int = Integer::from_n(att_hash);
Expand All @@ -156,6 +160,18 @@ where
unassigned_msg_hashes.push(msg_hashes_row);
unassigned_s_invs.push(s_inv_row);

//
// TODO: Update/remove this concept of "default pubkey" in the future.
// This "default pubkey" can cause confusion & unexpected issues.
//
// Here, if the pubkey is not given (None), the "default" pubkey is added automatically.
// This means that if there is only 1 real pubkey,
// the "unassigned_pks" would include NUM_NEIGHBORS pubkeys with default pubkey.
//
// Example:
// pks = [ Some(pk1), Some(pk2), None, None ]
// unassigned_pks = [ pk1, pk2, default_pk, default_pk ]
//
let pk = pks[i].clone().unwrap_or(PublicKey::default());
let unassigned_pk = UnassignedPublicKey::new(pk);
unassigned_pks.push(unassigned_pk);
Expand Down
28 changes: 20 additions & 8 deletions eigentrust-zk/src/circuits/dynamic_sets/native.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,6 @@ where
Self { attestation, signature }
}

/// Constructs a new empty attestation
pub fn empty(domain: N) -> Self {
let attestation = Attestation::<N> { domain, ..Default::default() };
let signature = Signature { r: Integer::one(), s: Integer::one(), ..Default::default() };

Self { attestation, signature }
}

/// Constructs a new empty attestation with about
pub fn empty_with_about(about: N, domain: N) -> Self {
let attestation = Attestation::<N> { about, domain, ..Default::default() };
Expand Down Expand Up @@ -230,6 +222,26 @@ impl<
op_hash
}

/// Unwraps a `Vec<Option<SignedAttestation>>`.
/// `None` values are replaced by empty signed attestations with the correct about field.
pub fn parse_op_group(
&mut self, op: Vec<Option<SignedAttestation<C, N, NUM_LIMBS, NUM_BITS, P>>>,
) -> Vec<SignedAttestation<C, N, NUM_LIMBS, NUM_BITS, P>> {
// Get participant set addresses
let set: Vec<N> = self.set.iter().map(|&(addr, _)| addr).collect();

op.into_iter()
.enumerate()
.map(|(index, attestation)| {
attestation.unwrap_or_else(|| {
SignedAttestation::<C, N, NUM_LIMBS, NUM_BITS, P>::empty_with_about(
set[index], self.domain,
)
})
})
.collect()
}

/// Method for filtering invalid opinions
fn filter_peers_ops(&self) -> HashMap<N, Vec<N>> {
let mut filtered_ops: HashMap<N, Vec<N>> = HashMap::new();
Expand Down
14 changes: 8 additions & 6 deletions eigentrust-zk/src/circuits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,12 @@ use crate::{
},
verifier::aggregator::native::NativeAggregator,
};
use halo2::halo2curves::{
bn256::{Bn256, Fr as Scalar},
secp256k1::Secp256k1Affine,
use halo2::{
halo2curves::{
bn256::{Bn256, Fr as Scalar},
secp256k1::Secp256k1Affine,
},
poly::kzg::commitment::KZGCommitmentScheme,
};
use num_rational::BigRational;

Expand Down Expand Up @@ -58,6 +61,8 @@ pub const ET_PARAMS_K: u32 = 20;
/// Default polynomial degree for KZG parameters for Threshold circuit.
pub const TH_PARAMS_K: u32 = 21;

/// KZG Commitment Scheme
pub type KZGParams = KZGCommitmentScheme<Bn256>;
/// Rational score
pub type RationalScore = BigRational;
/// Type alias for the native poseidon hasher with a width of 5 and bn254 params
Expand Down Expand Up @@ -106,7 +111,6 @@ pub type NativeAggregator4 = NativeAggregator<
PoseidonNativeSponge,
Bn254Params,
>;

/// Native EigenTrust set with 4 participants
pub type NativeEigenTrust4 = NativeEigenTrustSet<
NUM_NEIGHBOURS,
Expand Down Expand Up @@ -136,11 +140,9 @@ pub type EigenTrust4 = EigenTrustSet<
PoseidonNativeHasher,
SpongeHasher,
>;

/// Native Threshold for scores computed in EigenTrust4
pub type NativeThreshold4 =
Threshold<Scalar, NUM_DECIMAL_LIMBS, POWER_OF_TEN, NUM_NEIGHBOURS, INITIAL_SCORE>;

/// Threshold Circuit for scores computed in EigenTrust4
pub type Threshold4 = ThresholdCircuit<
Bn256,
Expand Down
2 changes: 1 addition & 1 deletion eigentrust-zk/src/circuits/threshold/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,7 @@ impl<
let composed_num = {
let mut limbs = num_decomposed_limbs.clone();
limbs.reverse();
#[allow(clippy::redundant_clone)]
let scale = max_limb_value.clone();

let mut val = limbs[0].clone();
Expand Down Expand Up @@ -677,7 +678,6 @@ mod tests {
use rand::thread_rng;

type E = Bn256;
type C = G1Affine;
type N = Fr;
type HN = PoseidonNativeHasher;
type SN = PoseidonNativeSponge;
Expand Down
1 change: 0 additions & 1 deletion eigentrust/README.md

This file was deleted.

21 changes: 7 additions & 14 deletions eigentrust/src/attestation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ use crate::{
use eigentrust_zk::{
circuits::{
dynamic_sets::native::{Attestation, SignedAttestation},
ECDSAKeypair, ECDSAPublicKey, ECDSASignature, HASHER_WIDTH, NUM_BITS, NUM_LIMBS,
ECDSAKeypair, ECDSAPublicKey, ECDSASignature, PoseidonNativeHasher, HASHER_WIDTH, NUM_BITS,
NUM_LIMBS,
},
halo2::halo2curves::{ff::FromUniformBytes, secp256k1::Secp256k1Affine},
integer::native::Integer,
params::{hasher::poseidon_bn254_5x5::Params, rns::secp256k1::Secp256k1_4_68},
poseidon::native::Poseidon,
params::rns::secp256k1::Secp256k1_4_68,
};
use ethers::types::{Address, Bytes, Uint8, H160, H256};

Expand Down Expand Up @@ -220,8 +220,7 @@ impl SignedAttestationEth {
let signature = ECDSASignature::from(signature_raw);

// Recover signed attestation hash
let att_hash =
attestation.hash::<HASHER_WIDTH, Poseidon<Scalar, HASHER_WIDTH, Params>>().to_bytes();
let att_hash = attestation.hash::<HASHER_WIDTH, PoseidonNativeHasher>().to_bytes();
let scalar_opt = SecpScalar::from_bytes(&att_hash);
let secp_scalar_att_hash = match scalar_opt.is_some().into() {
true => scalar_opt.unwrap(),
Expand Down Expand Up @@ -616,9 +615,7 @@ mod tests {
let attestation_raw: AttestationRaw = attestation_eth.clone().into();
let attestation_fr = attestation_eth.to_attestation_fr().unwrap();

let message = attestation_fr
.hash::<HASHER_WIDTH, Poseidon<Scalar, HASHER_WIDTH, Params>>()
.to_bytes();
let message = attestation_fr.hash::<HASHER_WIDTH, PoseidonNativeHasher>().to_bytes();
let message_fq = SecpScalar::from_bytes(&message).unwrap();

let signature = keypair.sign(message_fq, rng);
Expand All @@ -645,9 +642,7 @@ mod tests {
let attestation_eth = AttestationEth::default();
let attestation_fr = attestation_eth.to_attestation_fr().unwrap();

let message = attestation_fr
.hash::<HASHER_WIDTH, Poseidon<Scalar, HASHER_WIDTH, Params>>()
.to_bytes();
let message = attestation_fr.hash::<HASHER_WIDTH, PoseidonNativeHasher>().to_bytes();
let message_fq = SecpScalar::from_bytes(&message).unwrap();

let signature = keypair.sign(message_fq, rng);
Expand Down Expand Up @@ -698,9 +693,7 @@ mod tests {

let attestation_fr = attestation_eth.to_attestation_fr().unwrap();

let message = attestation_fr
.hash::<HASHER_WIDTH, Poseidon<Scalar, HASHER_WIDTH, Params>>()
.to_bytes();
let message = attestation_fr.hash::<HASHER_WIDTH, PoseidonNativeHasher>().to_bytes();
let message_fq = SecpScalar::from_bytes(&message).unwrap();

let signature = keypair.sign(message_fq, rng);
Expand Down
8 changes: 5 additions & 3 deletions eigentrust/src/circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
use crate::{attestation::SignedAttestationScalar, error::EigenError};
use eigentrust_zk::{
circuits::{ECDSAPublicKey, RationalScore, Threshold4},
circuits::{ECDSAPublicKey, EigenTrust4, RationalScore, Threshold4},
halo2::halo2curves::bn256::Fr as Scalar,
};
use ethers::types::Address;
Expand Down Expand Up @@ -61,6 +61,8 @@ pub struct ETSetup {
pub address_set: Vec<Address>,
/// Attestation matrix.
pub attestation_matrix: Vec<Vec<Option<SignedAttestationScalar>>>,
/// Eigentrust circuit.
pub circuit: EigenTrust4,
/// ECDSA public keys set.
pub ecdsa_set: Vec<Option<ECDSAPublicKey>>,
/// Public inputs.
Expand All @@ -73,10 +75,10 @@ impl ETSetup {
/// Constructs a new ETSetup instance.
pub fn new(
address_set: Vec<Address>, attestation_matrix: Vec<Vec<Option<SignedAttestationScalar>>>,
ecdsa_set: Vec<Option<ECDSAPublicKey>>, pub_inputs: ETPublicInputs,
circuit: EigenTrust4, ecdsa_set: Vec<Option<ECDSAPublicKey>>, pub_inputs: ETPublicInputs,
rational_scores: Vec<RationalScore>,
) -> Self {
Self { address_set, attestation_matrix, ecdsa_set, pub_inputs, rational_scores }
Self { address_set, attestation_matrix, circuit, ecdsa_set, pub_inputs, rational_scores }
}
}

Expand Down
Loading

0 comments on commit 5799ed4

Please sign in to comment.