Skip to content

Commit db616f7

Browse files
authored
Merge pull request #17 from lambdaclass/tip_hash
Tip hash
2 parents e4bc95d + 1e86a2a commit db616f7

5 files changed

Lines changed: 151 additions & 151 deletions

File tree

batcher/aligned-batcher/src/mina/mod.rs

Lines changed: 55 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,97 @@
1-
use std::array;
1+
use std::array::TryFromSliceError;
22

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

66
const STATE_HASH_SIZE: usize = 32;
77

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

1515
debug!("Checking Mina protocol state public inputs");
16-
if let Err(err) = check_protocol_state_pub(public_input) {
16+
if let Err(err) = check_pub_inputs(public_input) {
1717
warn!("Protocol state public inputs check failed: {}", err);
1818
return false;
1919
}
2020

2121
true
2222
}
2323

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

3231
Ok(())
3332
}
3433

35-
pub fn check_protocol_state_pub(protocol_state_pub: &[u8]) -> Result<(), String> {
36-
// TODO(xqft): check hash and binprot deserialization
37-
let candidate_protocol_state_len =
38-
check_protocol_state_and_hash(protocol_state_pub, STATE_HASH_SIZE)?;
34+
pub fn check_state(pub_inputs: &[u8], offset: &mut usize) -> Result<(), String> {
35+
let state_len: usize = pub_inputs
36+
.get(*offset..*offset + 4)
37+
.ok_or("Failed to slice state len".to_string())
38+
.and_then(|slice| {
39+
slice
40+
.try_into()
41+
.map_err(|err: TryFromSliceError| err.to_string())
42+
})
43+
.map(u32::from_be_bytes)
44+
.and_then(|len| usize::try_from(len).map_err(|err| err.to_string()))?;
45+
46+
pub_inputs
47+
.get(*offset + 4..*offset + 4 + state_len)
48+
.ok_or("Failed to slice state".to_string())
49+
.and_then(|bytes| std::str::from_utf8(bytes).map_err(|err| err.to_string()))
50+
.and_then(|base64| {
51+
BASE64_STANDARD
52+
.decode(base64)
53+
.map_err(|err| err.to_string())
54+
})?;
55+
*offset += 4 + state_len;
56+
57+
Ok(())
58+
}
3959

40-
let _tip_protocol_state_len = check_protocol_state_and_hash(
41-
protocol_state_pub,
42-
STATE_HASH_SIZE + 4 + candidate_protocol_state_len + STATE_HASH_SIZE,
43-
)?;
60+
pub fn check_pub_inputs(pub_inputs: &[u8]) -> Result<(), String> {
61+
let mut offset = 0;
62+
63+
check_hash(pub_inputs, &mut offset)?; // candidate hash
64+
check_hash(pub_inputs, &mut offset)?; // tip hash
65+
66+
check_state(pub_inputs, &mut offset)?; // candidate state
67+
check_state(pub_inputs, &mut offset)?; // tip state
4468

4569
Ok(())
4670
}
4771

48-
fn check_protocol_state_and_hash(protocol_state_pub: &[u8], start: usize) -> Result<usize, String> {
49-
let protocol_state_len_vec: Vec<_> = protocol_state_pub.iter().skip(start).take(4).collect();
50-
let protocol_state_len_bytes: [u8; 4] = array::from_fn(|i| protocol_state_len_vec[i].clone());
51-
let protocol_state_len = u32::from_be_bytes(protocol_state_len_bytes) as usize;
52-
53-
let protocol_state_bytes: Vec<_> = protocol_state_pub
54-
.iter()
55-
.skip(start + 4)
56-
.take(protocol_state_len)
57-
.map(|byte| byte.clone())
58-
.collect();
59-
let protocol_state_base64 =
60-
std::str::from_utf8(protocol_state_bytes.as_slice()).map_err(|err| err.to_string())?;
61-
BASE64_STANDARD
62-
.decode(protocol_state_base64)
63-
.map_err(|err| err.to_string())?;
64-
65-
Ok(protocol_state_len)
72+
pub fn check_proof(proof_bytes: &[u8]) -> Result<(), String> {
73+
std::str::from_utf8(proof_bytes)
74+
.map_err(|err| err.to_string())
75+
.and_then(|base64| {
76+
BASE64_URL_SAFE
77+
.decode(base64)
78+
.map_err(|err| err.to_string())
79+
})?;
80+
Ok(())
6681
}
6782

6883
#[cfg(test)]
6984
mod test {
70-
use super::verify_protocol_state_proof_integrity;
85+
use super::verify_proof_integrity;
7186

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

7792
#[test]
78-
fn verify_protocol_state_proof_integrity_does_not_fail() {
79-
assert!(verify_protocol_state_proof_integrity(
93+
fn verify_proof_integrity_does_not_fail() {
94+
assert!(verify_proof_integrity(
8095
PROTOCOL_STATE_PROOF_BYTES,
8196
PROTOCOL_STATE_PUB_BYTES,
8297
));

batcher/aligned-batcher/src/zk_utils/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::halo2::ipa::verify_halo2_ipa;
22
use crate::halo2::kzg::verify_halo2_kzg;
33
use crate::risc_zero::verify_risc_zero_proof;
44
use crate::sp1::verify_sp1_proof;
5-
use crate::{gnark::verify_gnark, mina::verify_protocol_state_proof_integrity};
5+
use crate::{gnark::verify_gnark, mina::verify_proof_integrity};
66
use aligned_sdk::core::types::{ProvingSystemId, VerificationData};
77
use log::{debug, warn};
88

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

0 commit comments

Comments
 (0)