Skip to content

Commit

Permalink
Merge branch 'mina' into mina_holesky
Browse files Browse the repository at this point in the history
  • Loading branch information
gabrielbosio committed Aug 12, 2024
2 parents 1882cb3 + db616f7 commit 5f3540f
Show file tree
Hide file tree
Showing 5 changed files with 151 additions and 151 deletions.
95 changes: 55 additions & 40 deletions batcher/aligned-batcher/src/mina/mod.rs
Original file line number Diff line number Diff line change
@@ -1,82 +1,97 @@
use std::array;
use std::array::TryFromSliceError;

use base64::prelude::*;
use log::{debug, warn};

const STATE_HASH_SIZE: usize = 32;

pub fn verify_protocol_state_proof_integrity(proof: &[u8], public_input: &[u8]) -> bool {
pub fn verify_proof_integrity(proof: &[u8], public_input: &[u8]) -> bool {
debug!("Checking Mina protocol state proof");
if let Err(err) = check_protocol_state_proof(proof) {
if let Err(err) = check_proof(proof) {
warn!("Protocol state proof check failed: {}", err);
return false;
}

debug!("Checking Mina protocol state public inputs");
if let Err(err) = check_protocol_state_pub(public_input) {
if let Err(err) = check_pub_inputs(public_input) {
warn!("Protocol state public inputs check failed: {}", err);
return false;
}

true
}

pub fn check_protocol_state_proof(protocol_state_proof_bytes: &[u8]) -> Result<(), String> {
// TODO(xqft): check binprot deserialization
let protocol_state_proof_base64 =
std::str::from_utf8(protocol_state_proof_bytes).map_err(|err| err.to_string())?;
BASE64_URL_SAFE
.decode(protocol_state_proof_base64)
.map_err(|err| err.to_string())?;
pub fn check_hash(pub_inputs: &[u8], offset: &mut usize) -> Result<(), String> {
pub_inputs
.get(*offset..*offset + STATE_HASH_SIZE)
.ok_or("Failed to slice candidate hash".to_string())?;

*offset += STATE_HASH_SIZE;

Ok(())
}

pub fn check_protocol_state_pub(protocol_state_pub: &[u8]) -> Result<(), String> {
// TODO(xqft): check hash and binprot deserialization
let candidate_protocol_state_len =
check_protocol_state_and_hash(protocol_state_pub, STATE_HASH_SIZE)?;
pub fn check_state(pub_inputs: &[u8], offset: &mut usize) -> Result<(), String> {
let state_len: usize = pub_inputs
.get(*offset..*offset + 4)
.ok_or("Failed to slice state len".to_string())
.and_then(|slice| {
slice
.try_into()
.map_err(|err: TryFromSliceError| err.to_string())
})
.map(u32::from_be_bytes)
.and_then(|len| usize::try_from(len).map_err(|err| err.to_string()))?;

pub_inputs
.get(*offset + 4..*offset + 4 + state_len)
.ok_or("Failed to slice state".to_string())
.and_then(|bytes| std::str::from_utf8(bytes).map_err(|err| err.to_string()))
.and_then(|base64| {
BASE64_STANDARD
.decode(base64)
.map_err(|err| err.to_string())
})?;
*offset += 4 + state_len;

Ok(())
}

let _tip_protocol_state_len = check_protocol_state_and_hash(
protocol_state_pub,
STATE_HASH_SIZE + 4 + candidate_protocol_state_len + STATE_HASH_SIZE,
)?;
pub fn check_pub_inputs(pub_inputs: &[u8]) -> Result<(), String> {
let mut offset = 0;

check_hash(pub_inputs, &mut offset)?; // candidate hash
check_hash(pub_inputs, &mut offset)?; // tip hash

check_state(pub_inputs, &mut offset)?; // candidate state
check_state(pub_inputs, &mut offset)?; // tip state

Ok(())
}

fn check_protocol_state_and_hash(protocol_state_pub: &[u8], start: usize) -> Result<usize, String> {
let protocol_state_len_vec: Vec<_> = protocol_state_pub.iter().skip(start).take(4).collect();
let protocol_state_len_bytes: [u8; 4] = array::from_fn(|i| protocol_state_len_vec[i].clone());
let protocol_state_len = u32::from_be_bytes(protocol_state_len_bytes) as usize;

let protocol_state_bytes: Vec<_> = protocol_state_pub
.iter()
.skip(start + 4)
.take(protocol_state_len)
.map(|byte| byte.clone())
.collect();
let protocol_state_base64 =
std::str::from_utf8(protocol_state_bytes.as_slice()).map_err(|err| err.to_string())?;
BASE64_STANDARD
.decode(protocol_state_base64)
.map_err(|err| err.to_string())?;

Ok(protocol_state_len)
pub fn check_proof(proof_bytes: &[u8]) -> Result<(), String> {
std::str::from_utf8(proof_bytes)
.map_err(|err| err.to_string())
.and_then(|base64| {
BASE64_URL_SAFE
.decode(base64)
.map_err(|err| err.to_string())
})?;
Ok(())
}

#[cfg(test)]
mod test {
use super::verify_protocol_state_proof_integrity;
use super::verify_proof_integrity;

const PROTOCOL_STATE_PROOF_BYTES: &[u8] =
include_bytes!("../../../../batcher/aligned/test_files/mina/protocol_state.proof");
const PROTOCOL_STATE_PUB_BYTES: &[u8] =
include_bytes!("../../../../batcher/aligned/test_files/mina/protocol_state.pub");

#[test]
fn verify_protocol_state_proof_integrity_does_not_fail() {
assert!(verify_protocol_state_proof_integrity(
fn verify_proof_integrity_does_not_fail() {
assert!(verify_proof_integrity(
PROTOCOL_STATE_PROOF_BYTES,
PROTOCOL_STATE_PUB_BYTES,
));
Expand Down
4 changes: 2 additions & 2 deletions batcher/aligned-batcher/src/zk_utils/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::halo2::ipa::verify_halo2_ipa;
use crate::halo2::kzg::verify_halo2_kzg;
use crate::risc_zero::verify_risc_zero_proof;
use crate::sp1::verify_sp1_proof;
use crate::{gnark::verify_gnark, mina::verify_protocol_state_proof_integrity};
use crate::{gnark::verify_gnark, mina::verify_proof_integrity};
use aligned_sdk::core::types::{ProvingSystemId, VerificationData};
use log::{debug, warn};

Expand Down Expand Up @@ -93,7 +93,7 @@ fn verify_internal(verification_data: &VerificationData) -> bool {
.pub_input
.as_ref()
.expect("Public input is required");
verify_protocol_state_proof_integrity(&verification_data.proof, pub_input)
verify_proof_integrity(&verification_data.proof, pub_input)
// TODO(xqft): add Pickles aggregator checks which are run alongside the Kimchi
// verifier. These checks are fast and if they aren't successful then the Pickles proof
// isn't valid.
Expand Down
Loading

0 comments on commit 5f3540f

Please sign in to comment.