From 9fd1a64289a9cbae9793efaa8e72e468d38a0614 Mon Sep 17 00:00:00 2001 From: Tjemmmic Date: Mon, 19 Aug 2024 21:50:23 -0500 Subject: [PATCH] BLS Pairing Debugging and Fix --- avs/incredible-squaring-avs/src/operator.rs | 15 +- .../src/anvil/testnet/incredible_squaring.rs | 74 +++--- test-utils/src/bin/incredible_squaring.rs | 5 +- utils/src/avs_registry/writer.rs | 2 + utils/src/crypto/bls.rs | 216 ++++++++++++++++-- utils/src/crypto/bn254.rs | 15 +- 6 files changed, 267 insertions(+), 60 deletions(-) diff --git a/avs/incredible-squaring-avs/src/operator.rs b/avs/incredible-squaring-avs/src/operator.rs index e080713..951d69e 100644 --- a/avs/incredible-squaring-avs/src/operator.rs +++ b/avs/incredible-squaring-avs/src/operator.rs @@ -278,7 +278,14 @@ impl Operator { .await .unwrap(); - let quorum_nums = Bytes::from(vec![0]); + let quorum_nums = Bytes::from([0x00]); + let bls_keypair = KeyPair::new( + eigen_utils::crypto::bls::PrivateKey::from_str( + "12248929636257230549931416853095037629726205319386239410403476017439825112537", + ) + .unwrap(), + ) + .unwrap(); let register_result = avs_registry_contract_manager .register_operator( &ecdsa_signing_key, @@ -358,7 +365,7 @@ impl Operator { log::info!("Received new task: {:?}", value); loop { - log::info!("About to wait for a new task submissions"); + log::info!("Waiting for new task submissions"); tokio::select! { Ok(new_task_created_log) = sub.recv() => { log::info!("Received new task: {:?}", new_task_created_log); @@ -376,6 +383,10 @@ impl Operator { } } + pub fn config(&self) -> NodeConfig { + self.config.clone() + } + fn process_new_task_created_log( &self, new_task_created_log: &Log, diff --git a/test-utils/src/anvil/testnet/incredible_squaring.rs b/test-utils/src/anvil/testnet/incredible_squaring.rs index 52e6403..a6f04c8 100644 --- a/test-utils/src/anvil/testnet/incredible_squaring.rs +++ b/test-utils/src/anvil/testnet/incredible_squaring.rs @@ -52,6 +52,7 @@ pub async fn run_incredible_squaring_testnet() -> ContractAddresses { let from = accounts[0].address(); let dev_account = accounts[0].address(); + let task_account = address!("a0Ee7A142d267C1f36714E4a8F75612F20a79720"); // This is the last Dev Account `accounts[9]` // Deploy initial contracts that don't depend on others @@ -94,11 +95,17 @@ pub async fn run_incredible_squaring_testnet() -> ContractAddresses { // Function with signature initialize(uint256,uint256,address,address) and selector 0x019e2729. let function_signature = "initialize(uint256,uint256,address,address)"; - let mut hasher = Keccak256::new(); - hasher.update(function_signature); - let function_selector = &hasher.finalize()[..4]; + // let mut hasher = Keccak256::new(); + // hasher.update(function_signature); + // let function_selector = &hasher.finalize()[..4]; - let encoded_data = encode_params!(function_selector, 1, 100, ierc20_addr, pauser_registry_addr); + let encoded_data = encode_params!( + function_signature, + 1, + 100, + ierc20_addr, + pauser_registry_addr + ); let strategy_proxy = TransparentUpgradeableProxy::deploy( provider.clone(), @@ -506,35 +513,36 @@ pub async fn run_incredible_squaring_testnet() -> ContractAddresses { ); log::info!("DELEGATION MANAGER ADDRESS: {:?}", delegation_manager_addr); - // let spawner_task_manager_address = task_manager_addr.clone(); - // // let spawner_provider = provider.clone(); - // let spawner_provider = provider; - // let task_spawner = async move { - // let manager = IncredibleSquaringTaskManager::new( - // spawner_task_manager_address, - // spawner_provider.clone(), - // ); - // loop { - // api.mine_one().await; - // log::info!("About to create new task"); - // tokio::time::sleep(std::time::Duration::from_millis(5000)).await; - // let result = manager - // .createNewTask(U256::from(2), 100u32, Bytes::from("0")) - // .send() - // .await - // .unwrap() - // .watch() - // .await - // .unwrap(); - // api.mine_one().await; - // log::info!("Created new task: {:?}", result); - // // let latest_task = manager.latestTaskNum().call().await.unwrap()._0; - // // log::info!("Latest task: {:?}", latest_task); - // // let task_hash = manager.allTaskHashes(latest_task).call().await.unwrap()._0; - // // log::info!("Task info: {:?}", task_hash); - // } - // }; - // tokio::spawn(task_spawner); + let spawner_task_manager_address = incredible_squaring_task_manager_addr.clone(); + // let spawner_provider = provider.clone(); + let spawner_provider = provider.clone(); + let task_spawner = async move { + let manager = IncredibleSquaringTaskManager::new( + spawner_task_manager_address, + spawner_provider.clone(), + ); + loop { + api.mine_one().await; + log::info!("About to create new task"); + tokio::time::sleep(std::time::Duration::from_millis(5000)).await; + let result = manager + .createNewTask(U256::from(2), 100u32, Bytes::from(vec![0])) + .from(task_account) + .send() + .await + .unwrap() + .watch() + .await + .unwrap(); + api.mine_one().await; + log::info!("Created new task: {:?}", result); + // let latest_task = manager.latestTaskNum().call().await.unwrap()._0; + // log::info!("Latest task: {:?}", latest_task); + // let task_hash = manager.allTaskHashes(latest_task).call().await.unwrap()._0; + // log::info!("Task info: {:?}", task_hash); + } + }; + tokio::spawn(task_spawner); ContractAddresses { service_manager: incredible_squaring_service_manager_addr, diff --git a/test-utils/src/bin/incredible_squaring.rs b/test-utils/src/bin/incredible_squaring.rs index 3ac0c2e..daf6761 100644 --- a/test-utils/src/bin/incredible_squaring.rs +++ b/test-utils/src/bin/incredible_squaring.rs @@ -3,6 +3,9 @@ use alloy_provider::Provider; use alloy_provider::ProviderBuilder; use alloy_signer_local::PrivateKeySigner; use alloy_transport_ws::WsConnect; +use ethers::prelude::contract; +use incredible_squaring_avs::aggregator::Aggregator; +use incredible_squaring_avs::avs::SetupConfig; use incredible_squaring_avs::operator::*; use k256::ecdsa::SigningKey; use k256::elliptic_curve::SecretKey; @@ -35,7 +38,7 @@ async fn operator_setup( operator_address: contract_addresses.operator.to_string(), enable_metrics: false, enable_node_api: false, - server_ip_port_address: "".to_string(), + server_ip_port_address: "127.0.0.1:8673".to_string(), }; let operator_info_service = OperatorInfoService {}; diff --git a/utils/src/avs_registry/writer.rs b/utils/src/avs_registry/writer.rs index b337308..dde34b2 100644 --- a/utils/src/avs_registry/writer.rs +++ b/utils/src/avs_registry/writer.rs @@ -93,6 +93,8 @@ impl AvsRegistryChainWriterTrait for AvsRegistryContractManager { pubkeyG2: RegistryCoordinator::G2Point { X: g2_pubkey_bn254.x, Y: g2_pubkey_bn254.y, + //X: [g2_pubkey_bn254.x[1], g2_pubkey_bn254.x[0]], + //Y: [g2_pubkey_bn254.y[1], g2_pubkey_bn254.y[0]], }, }; diff --git a/utils/src/crypto/bls.rs b/utils/src/crypto/bls.rs index ea79418..9b3ce51 100644 --- a/utils/src/crypto/bls.rs +++ b/utils/src/crypto/bls.rs @@ -180,8 +180,8 @@ impl CanonicalDeserialize for G2Point { impl G2Point { /// Create a new [G2Point] from [Field] components. This is unchecked and will not verify that the point is on the curve. pub fn new(x: [F; 2], y: [F; 2]) -> Self { - let x = [point_to_u256(x[0]), point_to_u256(x[1])]; - let y = [point_to_u256(y[0]), point_to_u256(y[1])]; + let x = [point_to_u256(x[1]), point_to_u256(x[0])]; + let y = [point_to_u256(y[1]), point_to_u256(y[0])]; Self { x, y } } @@ -279,12 +279,12 @@ pub fn ark_point_to_g1_point(pt: &G1Affine) -> G1Point { pub fn g2_point_to_ark_point(pt: &G2Point) -> G2Affine { G2Affine::new( QuadExtField { - c0: u256_to_point(pt.x[0]), - c1: u256_to_point(pt.x[1]), + c0: u256_to_point(pt.x[1]), + c1: u256_to_point(pt.x[0]), }, QuadExtField { - c0: u256_to_point(pt.y[0]), - c1: u256_to_point(pt.y[1]), + c0: u256_to_point(pt.y[1]), + c1: u256_to_point(pt.y[0]), }, ) } @@ -292,8 +292,8 @@ pub fn g2_point_to_ark_point(pt: &G2Point) -> G2Affine { /// Converts a [G2Affine] to a [G2Point]. pub fn ark_point_to_g2_point(pt: &G2Affine) -> G2Point { G2Point { - x: [point_to_u256(pt.x.c0), point_to_u256(pt.x.c1)], - y: [point_to_u256(pt.y.c0), point_to_u256(pt.y.c1)], + x: [point_to_u256(pt.x.c1), point_to_u256(pt.x.c0)], + y: [point_to_u256(pt.y.c1), point_to_u256(pt.y.c0)], } } @@ -349,9 +349,13 @@ impl Signature { self.g1_point.add(&other.g1_point); } - pub fn verify(&self, pubkey: &G2Point, message: &[u8; 32]) -> Result { - let g2_gen = G2Point::generator(); - let msg_affine = map_to_curve(message).into_affine(); + pub fn verify( + &self, + pubkey: &G2Point, + pre_hashed_message: &[u8; 32], + ) -> Result { + let g2_gen = ark_point_to_g2_point(&get_g2_generator()?); + let msg_affine = map_to_curve(pre_hashed_message).into_affine(); let msg_point = ark_point_to_g1_point(&msg_affine); let neg_sig = self.g1_point.neg(); @@ -524,22 +528,16 @@ impl KeyPair { } pub fn sign_message(&self, message: &[u8; 32]) -> Signature { - let sig_point = map_to_curve(message); - let sig = sig_point.mul_bigint(self.priv_key.0); + let hashed_point = map_to_curve(message); + let sig = hashed_point.mul_bigint(self.priv_key.0); Signature { g1_point: ark_point_to_g1_point(&sig.into_affine()), } } pub fn sign_hashed_to_curve_message(&self, g1_hashed_msg: &G1Point) -> Signature { - // let sig_point = g1_point_to_g1_projective(g1_hashed_msg); - // let sig = sig_point.mul_bigint(self.priv_key.0); - // Signature { - // g1_point: ark_point_to_g1_point(&sig.into_affine()), - // } - // - let sig_point = g1_point_to_ark_point(g1_hashed_msg); - let sig = sig_point.mul_bigint(self.priv_key.0); + let hashed_point = g1_point_to_ark_point(g1_hashed_msg); + let sig = hashed_point.mul_bigint(self.priv_key.0); Signature { g1_point: ark_point_to_g1_point(&sig.into_affine()), } @@ -561,6 +559,7 @@ impl KeyPair { #[cfg(test)] mod tests { + use super::{ark_point_to_g1_point, ark_point_to_g2_point, PrivateKey, U256}; use crate::crypto::bls::{g1_point_to_g1_projective, G1Point, G2Point, KeyPair}; use ark_bn254::Fq as F; use ark_bn254::{Fr, G1Affine, G1Projective, G2Affine, G2Projective}; @@ -568,6 +567,7 @@ mod tests { use ark_ff::UniformRand; use ark_ff::{BigInt, Field, One, PrimeField, Zero}; use rand::{thread_rng, Rng}; + use std::str::FromStr; #[tokio::test] async fn test_keypair_generation() { @@ -664,4 +664,178 @@ mod tests { let keypair_from_new = keypair_result_normal.unwrap(); assert_eq!(keypair_from_new.priv_key, keypair_from_string.priv_key); } + // + // #[tokio::test] + // async fn test_convert_to_g1_point() { + // let x_point = F::from_str( + // "17709620697113958145616918533531128159269167719799793368595970620022661612059", + // ) + // .unwrap(); + // let y_point = F::from_str( + // "9890439522434691655532127414660267222813910180198976870423582442696952349816", + // ) + // .unwrap(); + // let g1_affine = G1Affine::new(x_point, y_point); + // + // let alloy_g1_point = ark_point_to_g1_point(&g1_affine); + // assert_eq!( + // alloy_g1_point.x, + // U256::from_str( + // "17709620697113958145616918533531128159269167719799793368595970620022661612059" + // ) + // .unwrap() + // ); + // assert_eq!( + // alloy_g1_point.y, + // U256::from_str( + // "9890439522434691655532127414660267222813910180198976870423582442696952349816" + // ) + // .unwrap() + // ); + // } + // + // #[tokio::test] + // async fn test_convert_to_g2_point() { + // let x_point_c0 = F::from_str( + // "6834287759893774453556191528501556195232162436167606874229072410417955767882", + // ) + // .unwrap(); + // let x_point_c1 = F::from_str( + // "15529400123788596166111036611862227541174221446291015207340396747864347375335", + // ) + // .unwrap(); + // + // let y_point_c0 = F::from_str( + // "7616309349481520605447660298084926776417001188005125143383153219707218450524", + // ) + // .unwrap(); + // let y_point_c1 = F::from_str( + // "19775028091101520702581412350510183088819198056772055625089714355379667714558", + // ) + // .unwrap(); + // + // let x_point = ark_bn254::Fq2::new(x_point_c0, x_point_c1); + // let y_point = ark_bn254::Fq2::new(y_point_c0, y_point_c1); + // + // let g2_affine = G2Affine::new(x_point, y_point); + // + // let alloy_g2_point = ark_point_to_g2_point(&g2_affine); + // assert_eq!( + // alloy_g2_point.x[0], + // U256::from_str( + // "15529400123788596166111036611862227541174221446291015207340396747864347375335" + // ) + // .unwrap() + // ); + // assert_eq!( + // alloy_g2_point.x[1], + // U256::from_str( + // "6834287759893774453556191528501556195232162436167606874229072410417955767882" + // ) + // .unwrap() + // ); + // assert_eq!( + // alloy_g2_point.y[0], + // U256::from_str( + // "19775028091101520702581412350510183088819198056772055625089714355379667714558" + // ) + // .unwrap() + // ); + // assert_eq!( + // alloy_g2_point.y[1], + // U256::from_str( + // "7616309349481520605447660298084926776417001188005125143383153219707218450524" + // ) + // .unwrap() + // ); + // } + // + // #[tokio::test] + // async fn test_bls_key_pair() { + // let bls_priv_key = + // "12248929636257230549931416853095037629726205319386239410403476017439825112537"; + // let bls_key_pair = KeyPair::new(PrivateKey::from_str(bls_priv_key).unwrap()).unwrap(); + // + // assert_eq!( + // U256::from_limbs(*bls_key_pair.get_pub_key_g1().x.as_limbs()), + // U256::from_str( + // "277950648056014144722774518899051149098728246263316284984520891067822832300" + // ) + // .unwrap() + // ); + // assert_eq!( + // U256::from_limbs(*bls_key_pair.get_pub_key_g1().y.as_limbs()), + // U256::from_str( + // "16927236637669640540790285431111034664564710839671197540688155537113438534238" + // ) + // .unwrap() + // ); + // } + // + // #[test] + // fn test_map_to_curve() { + // let message: [u8; 32] = [ + // 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + // 25, 26, 27, 28, 29, 30, 31, 32, + // ]; + // let g1 = crate::crypto::bn254::map_to_curve(&message); + // + // assert_eq!( + // U256::from_limbs(g1.x.into_bigint().0), + // U256::from_str( + // "455867356320691211509944977504407603390036387149619137164185182714736811811" + // ) + // .unwrap() + // ); + // assert_eq!( + // U256::from_limbs(g1.y.into_bigint().0), + // U256::from_str( + // "9802125641729881429496664198939823213610051907104384160271670136040620850981" + // ) + // .unwrap() + // ); + // } + // + // #[test] + // fn test_sign_message() { + // let message: [u8; 32] = [ + // 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + // 25, 26, 27, 28, 29, 30, 31, 32, + // ]; + // let bls_priv_key = + // "12248929636257230549931416853095037629726205319386239410403476017439825112537"; + // let bls_key_pair = KeyPair::new(PrivateKey::from_str(bls_priv_key).unwrap()).unwrap(); + // + // + // let signature = bls_key_pair.sign_message(&message); + // assert_eq!( + // U256::from_limbs(*signature.g1_point.x.as_limbs()), + // U256::from_str( + // "6125087140203962697351933212367898471377426213402772883153680722977416765651" + // ) + // .unwrap() + // ); + // assert_eq!( + // U256::from_limbs(*signature.g1_point.y.as_limbs()), + // U256::from_str( + // "19120302240465611628345095276448175199636936878728446037184749040811421969742" + // ) + // .unwrap() + // ); + // } + // + // #[test] + // fn test_verify_message() { + // let message: [u8; 32] = [ + // 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + // 25, 26, 27, 28, 29, 30, 31, 32, + // ]; + // let bls_priv_key = + // "12248929636257230549931416853095037629726205319386239410403476017439825112537"; + // let bls_key_pair = KeyPair::new(PrivateKey::from_str(bls_priv_key).unwrap()).unwrap(); + // + // let signature = bls_key_pair.sign_message(&message); + // + // assert!(signature.verify(&bls_key_pair.get_pub_key_g2(), &message).unwrap()) + // } } diff --git a/utils/src/crypto/bn254.rs b/utils/src/crypto/bn254.rs index c80a4b9..a6f9bab 100644 --- a/utils/src/crypto/bn254.rs +++ b/utils/src/crypto/bn254.rs @@ -5,6 +5,8 @@ use ark_bn254::{Fr, G1Affine, G1Projective, G2Affine, G2Projective}; use ark_ec::AffineRepr; use ark_ff::{BigInteger, BigInteger256}; use ark_ff::{Field, One, PrimeField}; +use std::ops::Neg; +use std::str::FromStr; pub fn map_to_curve(digest: &[u8; 32]) -> G1Projective { let one = F::one(); @@ -28,14 +30,14 @@ pub fn map_to_curve(digest: &[u8; 32]) -> G1Projective { } } -// Helper for converting a PrimeField to its U256 representation for Ethereum compatibility +/// Helper for converting a PrimeField to its U256 representation for Ethereum compatibility pub fn u256_to_point(point: U256) -> F { let le: [u8; 32] = point.to_le_bytes(); F::from_le_bytes_mod_order(&le[..]) } -// Helper for converting a PrimeField to its U256 representation for Ethereum compatibility -// (U256 reads data as big endian) +/// Helper for converting a PrimeField to its U256 representation for Ethereum compatibility +/// (U256 reads data as big endian) pub fn point_to_u256(point: F) -> U256 { let point = point.into_bigint(); let point_bytes = point.to_bytes_be(); @@ -77,6 +79,13 @@ pub fn get_g2_generator() -> Result { Ok(g2_affine) } +pub fn get_g2_generator_neg() -> Result { + // let g2_affine = G2Affine::new(ark_bn254::g2::G2_GENERATOR_X, ark_bn254::g2::G2_GENERATOR_Y); + // let g2_affine = G2Affine::generator(); + let g2_gen = get_g2_generator()?; + Ok(g2_gen.neg()) +} + pub fn mul_by_generator_g1(pvt_key: Fr) -> Result { let g1_gen_result = get_g1_generator();