diff --git a/batcher/aligned-sdk/src/core/types.rs b/batcher/aligned-sdk/src/core/types.rs index f2b961a17..194f8dd61 100644 --- a/batcher/aligned-sdk/src/core/types.rs +++ b/batcher/aligned-sdk/src/core/types.rs @@ -104,7 +104,12 @@ impl From for VerificationDataCommitment { pub_input_commitment = hasher.finalize_reset().into(); } - // Compute proving system auxiliary data commitment + // Compute proving system auxiliary data commitment (verification_key | vm_program_code) + // This commitment ties the specific proof system data to its respective proof system, + // And the proof is verifies. Its correctness is enforced by the merkle root verification + // check in the Batcher and Operator. The `proof_commitment` is hashed in favor of the + // `proof` itself to avoid re-hashing the proof. + // This creates a downside for the user however as they must now supply the proof with there verification key when retrieving the vk_commitment. // FIXME(marian): This should probably be reworked, for the moment when the proving // system is SP1 or Risc0, `proving_system_aux_data` stands for information related to the @@ -114,10 +119,12 @@ impl From for VerificationDataCommitment { if let Some(vm_program_code) = &verification_data.vm_program_code { hasher.update(vm_program_code); hasher.update([proving_system_byte]); + hasher.update(proof_commitment); hasher.finalize_reset().into() } else if let Some(verification_key) = &verification_data.verification_key { hasher.update(verification_key); hasher.update([proving_system_byte]); + hasher.update(proof_commitment); hasher.finalize_reset().into() } else { [0u8; 32] diff --git a/batcher/aligned-sdk/src/sdk.rs b/batcher/aligned-sdk/src/sdk.rs index 6b77eb332..ccfec9b43 100644 --- a/batcher/aligned-sdk/src/sdk.rs +++ b/batcher/aligned-sdk/src/sdk.rs @@ -418,9 +418,10 @@ async fn _is_proof_verified( Ok(result) } -/// Returns the commitment for the verification key, taking into account the corresponding proving system. +/// Returns the commitment for the verification key, taking into account the corresponding proving system, and proof it verifies. /// # Arguments /// * `verification_key_bytes` - The serialized contents of the verification key. +/// * `verification_key_bytes` - The serialized contents of the proof. /// * `proving_system` - The corresponding proving system ID. /// # Returns /// * The commitment. @@ -428,12 +429,19 @@ async fn _is_proof_verified( /// * None. pub fn get_vk_commitment( verification_key_bytes: &[u8], + proof_bytes: &[u8], proving_system: ProvingSystemId, ) -> [u8; 32] { let proving_system_id_byte = proving_system.clone() as u8; let mut hasher = Keccak256::new(); + + // + hasher.update(proof_bytes); + let proof_commitment: [u8; 32] = hasher.finalize_reset().into(); + hasher.update(verification_key_bytes); hasher.update([proving_system_id_byte]); + hasher.update(proof_commitment); hasher.finalize().into() } diff --git a/batcher/aligned/src/main.rs b/batcher/aligned/src/main.rs index 2546070eb..1d442a4f4 100644 --- a/batcher/aligned/src/main.rs +++ b/batcher/aligned/src/main.rs @@ -188,6 +188,8 @@ pub struct VerifyProofOnchainArgs { pub struct GetVkCommitmentArgs { #[arg(name = "Verification key file path", long = "verification_key_file")] verification_key_file: PathBuf, + #[arg(name = "Proof file path", long = "proof_file")] + proof_file: PathBuf, #[arg(name = "Proving system", long = "proving_system")] proving_system: ProvingSystemArg, #[arg(name = "Output file", long = "output")] @@ -420,9 +422,11 @@ async fn main() -> Result<(), AlignedError> { } GetVkCommitment(args) => { let verification_key_bytes = read_file(args.verification_key_file)?; + let proof_bytes = read_file(args.proof_file)?; let proving_system = args.proving_system.into(); - let vk_commitment = get_vk_commitment(&verification_key_bytes, proving_system); + let vk_commitment = + get_vk_commitment(&verification_key_bytes, &proof_bytes, proving_system); info!("Commitment: {}", hex::encode(vk_commitment)); if let Some(output_file) = args.output_file { diff --git a/docs/2_architecture/1_fast_mode.md b/docs/2_architecture/1_fast_mode.md index a043e1248..ba0c30e14 100644 --- a/docs/2_architecture/1_fast_mode.md +++ b/docs/2_architecture/1_fast_mode.md @@ -66,7 +66,7 @@ Each leaf contains the following information: - A commitment to the public input of the proof. - A commitment to the proof -- A commitment to the program or a commitment to the verification key, plus the Proving System/verifier used. +- A commitment to the program or a commitment to the verification key, plus the Proving System/verifier used and Proof that was verified using this verification key. - The address of the proof’s generator/submitter (optional). A diagram for the batch is shown on the figure below: diff --git a/docs/3_guides/2_integrating_aligned_into_your_application.md b/docs/3_guides/2_integrating_aligned_into_your_application.md index 038630601..44f09bcde 100644 --- a/docs/3_guides/2_integrating_aligned_into_your_application.md +++ b/docs/3_guides/2_integrating_aligned_into_your_application.md @@ -25,7 +25,7 @@ The Aligned CLI provides a way for you to get the verification key commitment wi You can do this by running the following command: ```bash -aligned get-vk-commitment --verification_key_file --proving_system +aligned get-vk-commitment --verification_key_file --proof_file --proving_system ``` The following is an example of how to call the `verifyBatchInclusionMethod` from the `AlignedServiceManager` contract in your smart contract. diff --git a/operator/merkle_tree/lib/src/lib.rs b/operator/merkle_tree/lib/src/lib.rs index d5b55669d..9e0f760fa 100644 --- a/operator/merkle_tree/lib/src/lib.rs +++ b/operator/merkle_tree/lib/src/lib.rs @@ -66,10 +66,7 @@ mod tests { merkle_root_file.read_to_end(&mut root_vec).unwrap(); let mut merkle_root = [0; 32]; - merkle_root.copy_from_slice( - &hex::decode(&root_vec) - .unwrap(), - ); + merkle_root.copy_from_slice(&hex::decode(&root_vec).unwrap()); let result = verify_merkle_tree_batch_ffi(bytes_vec.as_ptr(), bytes_vec.len(), &merkle_root); @@ -86,10 +83,7 @@ mod tests { merkle_root_file.read_to_end(&mut root_vec).unwrap(); let mut merkle_root = [0; 32]; - merkle_root.copy_from_slice( - &hex::decode(&root_vec) - .unwrap(), - ); + merkle_root.copy_from_slice(&hex::decode(&root_vec).unwrap()); let result = verify_merkle_tree_batch_ffi(bytes_vec.as_ptr(), bytes_vec.len(), &merkle_root); @@ -106,10 +100,7 @@ mod tests { merkle_root_file.read_to_end(&mut root_vec).unwrap(); let mut merkle_root = [0; 32]; - merkle_root.copy_from_slice( - &hex::decode(&root_vec) - .unwrap(), - ); + merkle_root.copy_from_slice(&hex::decode(&root_vec).unwrap()); let result = verify_merkle_tree_batch_ffi(bytes_vec.as_ptr(), bytes_vec.len(), &merkle_root); diff --git a/operator/pkg/operator.go b/operator/pkg/operator.go index 558f72878..57b0330be 100644 --- a/operator/pkg/operator.go +++ b/operator/pkg/operator.go @@ -37,20 +37,20 @@ import ( ) type Operator struct { - Config config.OperatorConfig - Address ethcommon.Address - Socket string - Timeout time.Duration - PrivKey *ecdsa.PrivateKey - KeyPair *bls.KeyPair - OperatorId eigentypes.OperatorId - avsSubscriber chainio.AvsSubscriber + Config config.OperatorConfig + Address ethcommon.Address + Socket string + Timeout time.Duration + PrivKey *ecdsa.PrivateKey + KeyPair *bls.KeyPair + OperatorId eigentypes.OperatorId + avsSubscriber chainio.AvsSubscriber NewTaskCreatedChanV2 chan *servicemanager.ContractAlignedLayerServiceManagerNewBatchV2 NewTaskCreatedChanV3 chan *servicemanager.ContractAlignedLayerServiceManagerNewBatchV3 - Logger logging.Logger - aggRpcClient AggregatorRpcClient - metricsReg *prometheus.Registry - metrics *metrics.Metrics + Logger logging.Logger + aggRpcClient AggregatorRpcClient + metricsReg *prometheus.Registry + metrics *metrics.Metrics //Socket string //Timeout time.Duration } @@ -110,16 +110,16 @@ func NewOperatorFromConfig(configuration config.OperatorConfig) (*Operator, erro operatorMetrics := metrics.NewMetrics(configuration.Operator.MetricsIpPortAddress, reg, logger) operator := &Operator{ - Config: configuration, - Logger: logger, - avsSubscriber: *avsSubscriber, - Address: address, + Config: configuration, + Logger: logger, + avsSubscriber: *avsSubscriber, + Address: address, NewTaskCreatedChanV2: newTaskCreatedChanV2, NewTaskCreatedChanV3: newTaskCreatedChanV3, - aggRpcClient: *rpcClient, - OperatorId: operatorId, - metricsReg: reg, - metrics: operatorMetrics, + aggRpcClient: *rpcClient, + OperatorId: operatorId, + metricsReg: reg, + metrics: operatorMetrics, // Timeout // Socket } @@ -127,7 +127,6 @@ func NewOperatorFromConfig(configuration config.OperatorConfig) (*Operator, erro return operator, nil } - func (o *Operator) SubscribeToNewTasksV2() (chan error, error) { return o.avsSubscriber.SubscribeToNewTasksV2(o.NewTaskCreatedChanV2) } @@ -206,10 +205,10 @@ func (o *Operator) handleNewBatchLogV2(newBatchLog *servicemanager.ContractAlign signedTaskResponse := types.SignedTaskResponse{ BatchIdentifierHash: batchIdentifierHash, - BatchMerkleRoot: newBatchLog.BatchMerkleRoot, - SenderAddress: newBatchLog.SenderAddress, - BlsSignature: *responseSignature, - OperatorId: o.OperatorId, + BatchMerkleRoot: newBatchLog.BatchMerkleRoot, + SenderAddress: newBatchLog.SenderAddress, + BlsSignature: *responseSignature, + OperatorId: o.OperatorId, } o.Logger.Infof("Signed Task Response to send: BatchIdentifierHash=%s, BatchMerkleRoot=%s, SenderAddress=%s", hex.EncodeToString(signedTaskResponse.BatchIdentifierHash[:]), @@ -277,10 +276,10 @@ func (o *Operator) handleNewBatchLogV3(newBatchLog *servicemanager.ContractAlign signedTaskResponse := types.SignedTaskResponse{ BatchIdentifierHash: batchIdentifierHash, - BatchMerkleRoot: newBatchLog.BatchMerkleRoot, - SenderAddress: newBatchLog.SenderAddress, - BlsSignature: *responseSignature, - OperatorId: o.OperatorId, + BatchMerkleRoot: newBatchLog.BatchMerkleRoot, + SenderAddress: newBatchLog.SenderAddress, + BlsSignature: *responseSignature, + OperatorId: o.OperatorId, } o.Logger.Infof("Signed Task Response to send: BatchIdentifierHash=%s, BatchMerkleRoot=%s, SenderAddress=%s", hex.EncodeToString(signedTaskResponse.BatchIdentifierHash[:]),