Skip to content

Commit 279aa75

Browse files
committed
Improve Mina verification FFI
- Change proof and pub input types from array to C pointer - Remove max size constants - Now the batcher does not use FFI to verify Mina proofs
1 parent 220546a commit 279aa75

File tree

6 files changed

+64
-115
lines changed

6 files changed

+64
-115
lines changed

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

Lines changed: 4 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ use crate::sp1::verify_sp1_proof;
44
use aligned_sdk::core::types::{ProvingSystemId, VerificationData};
55
use ethers::types::U256;
66
use log::{debug, warn};
7-
use mina_account_verifier_ffi::verify_account_inclusion_ffi;
8-
use mina_state_verifier_ffi::verify_mina_state_ffi;
7+
use mina_account_verifier_ffi::verify_account_inclusion;
8+
use mina_state_verifier_ffi::verify_mina_state;
99

1010
pub(crate) async fn verify(verification_data: &VerificationData) -> bool {
1111
let verification_data = verification_data.clone();
@@ -67,45 +67,15 @@ fn verify_internal(verification_data: &VerificationData) -> bool {
6767
return false;
6868
};
6969

70-
const MAX_PROOF_SIZE: usize = 48 * 1024;
71-
const MAX_PUB_INPUT_SIZE: usize = 6 * 1024;
72-
73-
let mut proof_buffer = [0; MAX_PROOF_SIZE];
74-
for (buffer_item, proof_item) in proof_buffer.iter_mut().zip(&verification_data.proof) {
75-
*buffer_item = *proof_item;
76-
}
77-
let proof_len = verification_data.proof.len();
78-
79-
let mut pub_input_buffer = [0; MAX_PUB_INPUT_SIZE];
80-
for (buffer_item, pub_input_item) in pub_input_buffer.iter_mut().zip(pub_input) {
81-
*buffer_item = *pub_input_item;
82-
}
83-
let pub_input_len = pub_input.len();
84-
85-
verify_mina_state_ffi(&proof_buffer, proof_len, &pub_input_buffer, pub_input_len)
70+
verify_mina_state(&verification_data.proof, &pub_input)
8671
}
8772
ProvingSystemId::MinaAccount => {
8873
let Some(pub_input) = verification_data.pub_input.as_ref() else {
8974
warn!("Mina Account public input is missing");
9075
return false;
9176
};
9277

93-
const MAX_PROOF_SIZE: usize = 16 * 1024;
94-
const MAX_PUB_INPUT_SIZE: usize = 6 * 1024;
95-
96-
let mut proof_buffer = [0; MAX_PROOF_SIZE];
97-
for (buffer_item, proof_item) in proof_buffer.iter_mut().zip(&verification_data.proof) {
98-
*buffer_item = *proof_item;
99-
}
100-
let proof_len = verification_data.proof.len();
101-
102-
let mut pub_input_buffer = [0; MAX_PUB_INPUT_SIZE];
103-
for (buffer_item, pub_input_item) in pub_input_buffer.iter_mut().zip(pub_input) {
104-
*buffer_item = *pub_input_item;
105-
}
106-
let pub_input_len = pub_input.len();
107-
108-
verify_account_inclusion_ffi(&proof_buffer, proof_len, &pub_input_buffer, pub_input_len)
78+
verify_account_inclusion(&verification_data.proof, &pub_input)
10979
}
11080
}
11181
}

operator/mina/lib/src/lib.rs

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -34,35 +34,40 @@ lazy_static! {
3434
static ref MINA_SRS: SRS<Vesta> = SRS::<Vesta>::create(Fq::SRS_DEPTH);
3535
}
3636

37-
// TODO(xqft): check proof size
38-
const MAX_PROOF_SIZE: usize = 48 * 1024;
39-
const MAX_PUB_INPUT_SIZE: usize = 6 * 1024;
40-
4137
#[no_mangle]
4238
pub extern "C" fn verify_mina_state_ffi(
43-
proof_buffer: &[u8; MAX_PROOF_SIZE],
39+
proof_bytes: *const u8,
4440
proof_len: usize,
45-
pub_input_buffer: &[u8; MAX_PUB_INPUT_SIZE],
41+
pub_input_bytes: *const u8,
4642
pub_input_len: usize,
4743
) -> bool {
48-
let Some(proof_buffer_slice) = proof_buffer.get(..proof_len) else {
49-
error!("Proof length argument is greater than max proof size");
44+
if proof_bytes.is_null() || pub_input_bytes.is_null() {
45+
error!("Input buffer null");
5046
return false;
51-
};
47+
}
5248

53-
let Some(pub_input_buffer_slice) = pub_input_buffer.get(..pub_input_len) else {
54-
error!("Public input length argument is greater than max public input size");
49+
if proof_len == 0 || pub_input_len == 0 {
50+
error!("Input buffer length zero size");
5551
return false;
56-
};
52+
}
53+
54+
let proof_bytes = unsafe { std::slice::from_raw_parts(proof_bytes, proof_len as usize) };
55+
56+
let pub_input_bytes =
57+
unsafe { std::slice::from_raw_parts(pub_input_bytes, proof_len as usize) };
58+
59+
verify_mina_state(proof_bytes, pub_input_bytes)
60+
}
5761

58-
let proof: MinaStateProof = match bincode::deserialize(proof_buffer_slice) {
62+
pub fn verify_mina_state(proof_bytes: &[u8], pub_input_bytes: &[u8]) -> bool {
63+
let proof: MinaStateProof = match bincode::deserialize(proof_bytes) {
5964
Ok(proof) => proof,
6065
Err(err) => {
6166
error!("Failed to deserialize state proof: {}", err);
6267
return false;
6368
}
6469
};
65-
let pub_inputs: MinaStatePubInputs = match bincode::deserialize(pub_input_buffer_slice) {
70+
let pub_inputs: MinaStatePubInputs = match bincode::deserialize(pub_input_bytes) {
6671
Ok(pub_inputs) => pub_inputs,
6772
Err(err) => {
6873
error!("Failed to deserialize state pub inputs: {}", err);
@@ -228,7 +233,7 @@ mod test {
228233

229234
#[test]
230235
fn valid_mina_state_proof_verifies() {
231-
let mut proof_buffer = [0u8; super::MAX_PROOF_SIZE];
236+
let mut proof_buffer = [0u8; PROOF_BYTES.len()];
232237
let proof_size = PROOF_BYTES.len();
233238
assert!(proof_size <= proof_buffer.len());
234239
proof_buffer[..proof_size].clone_from_slice(PROOF_BYTES);
@@ -245,7 +250,7 @@ mod test {
245250

246251
#[test]
247252
fn mina_state_proof_with_bad_bridge_tip_hash_does_not_verify() {
248-
let mut proof_buffer = [0u8; super::MAX_PROOF_SIZE];
253+
let mut proof_buffer = [0u8; PROOF_BYTES.len()];
249254
let proof_size = PROOF_BYTES.len();
250255
assert!(proof_size <= proof_buffer.len());
251256
proof_buffer[..proof_size].clone_from_slice(PROOF_BYTES);
@@ -262,7 +267,7 @@ mod test {
262267

263268
#[test]
264269
fn empty_mina_state_proof_does_not_verify() {
265-
let proof_buffer = [0u8; super::MAX_PROOF_SIZE];
270+
let proof_buffer = [0u8; PROOF_BYTES.len()];
266271
let proof_size = PROOF_BYTES.len();
267272

268273
let mut pub_input_buffer = [0u8; super::MAX_PUB_INPUT_SIZE];
@@ -277,7 +282,7 @@ mod test {
277282

278283
#[test]
279284
fn valid_mina_state_proof_with_empty_pub_input_does_not_verify() {
280-
let mut proof_buffer = [0u8; super::MAX_PROOF_SIZE];
285+
let mut proof_buffer = [0u8; PROOF_BYTES.len()];
281286
let proof_size = PROOF_BYTES.len();
282287
assert!(proof_size <= proof_buffer.len());
283288
proof_buffer[..proof_size].clone_from_slice(PROOF_BYTES);
@@ -292,8 +297,8 @@ mod test {
292297

293298
#[test]
294299
fn valid_mina_state_proof_with_greater_proof_size_does_not_verify() {
295-
let mut proof_buffer = [0u8; super::MAX_PROOF_SIZE];
296-
let wrong_proof_size = super::MAX_PROOF_SIZE + 1;
300+
let mut proof_buffer = [0u8; PROOF_BYTES.len()];
301+
let wrong_proof_size = PROOF_BYTES.len() + 1;
297302
proof_buffer[..PROOF_BYTES.len()].clone_from_slice(PROOF_BYTES);
298303

299304
let mut pub_input_buffer = [0u8; super::MAX_PUB_INPUT_SIZE];
@@ -312,7 +317,7 @@ mod test {
312317

313318
#[test]
314319
fn valid_mina_state_proof_with_greater_pub_input_size_does_not_verify() {
315-
let mut proof_buffer = [0u8; super::MAX_PROOF_SIZE];
320+
let mut proof_buffer = [0u8; PROOF_BYTES.len()];
316321
let proof_size = PROOF_BYTES.len();
317322
assert!(proof_size <= proof_buffer.len());
318323
proof_buffer[..proof_size].clone_from_slice(PROOF_BYTES);

operator/mina/mina.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,20 @@ import (
1313
"unsafe"
1414
)
1515

16-
// TODO(xqft): check proof size
17-
const MAX_PROOF_SIZE = 48 * 1024
18-
const MAX_PUB_INPUT_SIZE = 6 * 1024
19-
2016
func timer() func() {
2117
start := time.Now()
2218
return func() {
2319
fmt.Printf("Mina block verification took %v\n", time.Since(start))
2420
}
2521
}
2622

27-
func VerifyMinaState(proofBuffer [MAX_PROOF_SIZE]byte, proofLen uint, pubInputBuffer [MAX_PUB_INPUT_SIZE]byte, pubInputLen uint) bool {
23+
func VerifyMinaState(proofBuffer []byte, proofLen uint, pubInputBuffer []byte, pubInputLen uint) bool {
2824
defer timer()()
25+
26+
if len(proofBuffer) == 0 || len(pubInputBuffer) == 0 {
27+
return false
28+
}
29+
2930
proofPtr := (*C.uchar)(unsafe.Pointer(&proofBuffer[0]))
3031
pubInputPtr := (*C.uchar)(unsafe.Pointer(&pubInputBuffer[0]))
3132
return (bool)(C.verify_mina_state_ffi(proofPtr, (C.uint)(proofLen), pubInputPtr, (C.uint)(pubInputLen)))

operator/mina_account/lib/src/lib.rs

Lines changed: 25 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -9,31 +9,36 @@ use mina_tree::Account;
99

1010
mod merkle_verifier;
1111

12-
// TODO(xqft): check sizes
13-
const MAX_PROOF_SIZE: usize = 16 * 1024;
14-
const MAX_PUB_INPUT_SIZE: usize = 6 * 1024;
15-
1612
#[no_mangle]
1713
pub extern "C" fn verify_account_inclusion_ffi(
18-
proof_buffer: &[u8; MAX_PROOF_SIZE],
14+
proof_bytes: *const u8,
1915
proof_len: usize,
20-
pub_input_buffer: &[u8; MAX_PUB_INPUT_SIZE],
16+
pub_input_bytes: *const u8,
2117
pub_input_len: usize,
2218
) -> bool {
23-
let Some(proof_buffer_slice) = proof_buffer.get(..proof_len) else {
24-
error!("Proof length argument is greater than max proof size");
19+
if proof_bytes.is_null() || pub_input_bytes.is_null() {
20+
error!("Input buffer null");
2521
return false;
26-
};
22+
}
2723

28-
let Some(pub_input_buffer_slice) = pub_input_buffer.get(..pub_input_len) else {
29-
error!("Public input length argument is greater than max public input size");
24+
if proof_len == 0 || pub_input_len == 0 {
25+
error!("Input buffer length zero size");
3026
return false;
31-
};
27+
}
28+
29+
let proof_bytes = unsafe { std::slice::from_raw_parts(proof_bytes, proof_len as usize) };
3230

31+
let pub_input_bytes =
32+
unsafe { std::slice::from_raw_parts(pub_input_bytes, proof_len as usize) };
33+
34+
verify_account_inclusion(proof_bytes, pub_input_bytes)
35+
}
36+
37+
pub fn verify_account_inclusion(proof_bytes: &[u8], pub_input_bytes: &[u8]) -> bool {
3338
let MinaAccountProof {
3439
merkle_path,
3540
account,
36-
} = match bincode::deserialize(proof_buffer_slice) {
41+
} = match bincode::deserialize(proof_bytes) {
3742
Ok(proof) => proof,
3843
Err(err) => {
3944
error!("Failed to deserialize account proof: {}", err);
@@ -43,7 +48,7 @@ pub extern "C" fn verify_account_inclusion_ffi(
4348
let MinaAccountPubInputs {
4449
ledger_hash,
4550
encoded_account,
46-
} = match bincode::deserialize(pub_input_buffer_slice) {
51+
} = match bincode::deserialize(pub_input_bytes) {
4752
Ok(pub_inputs) => pub_inputs,
4853
Err(err) => {
4954
error!("Failed to deserialize account pub inputs: {}", err);
@@ -89,47 +94,27 @@ mod test {
8994

9095
#[test]
9196
fn valid_account_state_proof_verifies() {
92-
let mut proof_buffer = [0u8; super::MAX_PROOF_SIZE];
93-
let proof_size = PROOF_BYTES.len();
94-
assert!(proof_size <= proof_buffer.len());
95-
proof_buffer[..proof_size].clone_from_slice(PROOF_BYTES);
96-
97-
let mut pub_input_buffer = [0u8; super::MAX_PUB_INPUT_SIZE];
98-
let pub_input_size = PUB_INPUT_BYTES.len();
99-
assert!(pub_input_size <= pub_input_buffer.len());
100-
pub_input_buffer[..pub_input_size].clone_from_slice(PUB_INPUT_BYTES);
101-
102-
let result = verify_account_inclusion_ffi(
103-
&proof_buffer,
104-
proof_size,
105-
&pub_input_buffer,
106-
pub_input_size,
107-
);
97+
let result = verify_account_inclusion(PROOF_BYTES, PUB_INPUT_BYTES);
10898
assert!(result);
10999
}
110100

111101
#[test]
112102
fn empty_account_state_proof_does_not_verify() {
113-
let proof_buffer = [0u8; super::MAX_PROOF_SIZE];
103+
let proof_buffer = [0u8; PROOF_BYTES.len()];
114104
let proof_size = PROOF_BYTES.len();
115105

116106
let mut pub_input_buffer = [0u8; super::MAX_PUB_INPUT_SIZE];
117107
let pub_input_size = PUB_INPUT_BYTES.len();
118108
assert!(pub_input_size <= pub_input_buffer.len());
119109
pub_input_buffer[..pub_input_size].clone_from_slice(PUB_INPUT_BYTES);
120110

121-
let result = verify_account_inclusion_ffi(
122-
&proof_buffer,
123-
proof_size,
124-
&pub_input_buffer,
125-
pub_input_size,
126-
);
111+
let result = verify_account_inclusion(&proof_buffer, &pub_input_buffer, pub_input_size);
127112
assert!(!result);
128113
}
129114

130115
#[test]
131116
fn valid_account_state_proof_with_empty_pub_input_does_not_verify() {
132-
let mut proof_buffer = [0u8; super::MAX_PROOF_SIZE];
117+
let mut proof_buffer = [0u8; PROOF_BYTES.len()];
133118
let proof_size = PROOF_BYTES.len();
134119
assert!(proof_size <= proof_buffer.len());
135120
proof_buffer[..proof_size].clone_from_slice(PROOF_BYTES);
@@ -148,7 +133,7 @@ mod test {
148133

149134
#[test]
150135
fn valid_account_state_proof_with_greater_proof_size_does_not_verify() {
151-
let mut proof_buffer = [0u8; super::MAX_PROOF_SIZE];
136+
let mut proof_buffer = [0u8; PROOF_BYTES.len()];
152137
let wrong_proof_size = MAX_PROOF_SIZE + 1;
153138
proof_buffer[..PROOF_BYTES.len()].clone_from_slice(PROOF_BYTES);
154139

@@ -168,7 +153,7 @@ mod test {
168153

169154
#[test]
170155
fn valid_account_state_proof_with_greater_pub_input_size_does_not_verify() {
171-
let mut proof_buffer = [0u8; super::MAX_PROOF_SIZE];
156+
let mut proof_buffer = [0u8; PROOF_BYTES.len()];
172157
let proof_size = PROOF_BYTES.len();
173158
assert!(proof_size <= proof_buffer.len());
174159
proof_buffer[..proof_size].clone_from_slice(PROOF_BYTES);

operator/mina_account/mina_account.go

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,14 @@ import (
1313
"unsafe"
1414
)
1515

16-
// TODO(xqft): check proof size
17-
const MAX_PROOF_SIZE = 16 * 1024
18-
const MAX_PUB_INPUT_SIZE = 6 * 1024
19-
2016
func timer() func() {
2117
start := time.Now()
2218
return func() {
2319
fmt.Printf("Mina account verification took %v\n", time.Since(start))
2420
}
2521
}
2622

27-
func VerifyAccountInclusion(proofBuffer [MAX_PROOF_SIZE]byte, proofLen uint, pubInputBuffer [MAX_PUB_INPUT_SIZE]byte, pubInputLen uint) bool {
23+
func VerifyAccountInclusion(proofBuffer []byte, proofLen uint, pubInputBuffer []byte, pubInputLen uint) bool {
2824
defer timer()()
2925
proofPtr := (*C.uchar)(unsafe.Pointer(&proofBuffer[0]))
3026
pubInputPtr := (*C.uchar)(unsafe.Pointer(&pubInputBuffer[0]))

operator/pkg/operator.go

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -533,24 +533,16 @@ func (o *Operator) verify(verificationData VerificationData, disabledVerifiersBi
533533
case common.Mina:
534534
proofLen := (uint)(len(verificationData.Proof))
535535
pubInputLen := (uint)(len(verificationData.PubInput))
536-
proofBuffer := make([]byte, mina.MAX_PROOF_SIZE)
537-
copy(proofBuffer, verificationData.Proof)
538-
pubInputBuffer := make([]byte, mina.MAX_PUB_INPUT_SIZE)
539-
copy(pubInputBuffer, verificationData.PubInput)
540536

541-
verificationResult := mina.VerifyMinaState(([mina.MAX_PROOF_SIZE]byte)(proofBuffer), proofLen, ([mina.MAX_PUB_INPUT_SIZE]byte)(pubInputBuffer), (uint)(pubInputLen))
537+
verificationResult := mina.VerifyMinaState(verificationData.Proof, proofLen, verificationData.PubInput, (uint)(pubInputLen))
542538
o.Logger.Infof("Mina state proof verification result: %t", verificationResult)
543539
// TODO: Remove the nil value passed as err argument
544540
o.handleVerificationResult(results, verificationResult, nil, "Mina state proof verification")
545541
case common.MinaAccount:
546542
proofLen := (uint)(len(verificationData.Proof))
547543
pubInputLen := (uint)(len(verificationData.PubInput))
548-
proofBuffer := make([]byte, mina.MAX_PROOF_SIZE)
549-
copy(proofBuffer, verificationData.Proof)
550-
pubInputBuffer := make([]byte, mina.MAX_PUB_INPUT_SIZE)
551-
copy(pubInputBuffer, verificationData.PubInput)
552544

553-
verificationResult := mina_account.VerifyAccountInclusion(([mina_account.MAX_PROOF_SIZE]byte)(proofBuffer), proofLen, ([mina_account.MAX_PUB_INPUT_SIZE]byte)(pubInputBuffer), (uint)(pubInputLen))
545+
verificationResult := mina_account.VerifyAccountInclusion(verificationData.Proof, proofLen, verificationData.PubInput, (uint)(pubInputLen))
554546
o.Logger.Infof("Mina account inclusion proof verification result: %t", verificationResult)
555547
// TODO: Remove the nil value passed as err argument
556548
o.handleVerificationResult(results, verificationResult, nil, "Mina account state proof verification")

0 commit comments

Comments
 (0)