Skip to content

Commit fbd3b5b

Browse files
author
Naohiro Yoshida
committed
add sidecar blob check
1 parent c751cb1 commit fbd3b5b

File tree

2 files changed

+92
-19
lines changed

2 files changed

+92
-19
lines changed

derivation/src/errors.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ pub enum Error {
4040
NoPreimageDataFoundInVerifyBlob(Vec<u8>, Box<Error>),
4141
#[error("NoPreimageKeyFoundInPrecompile: err={0:?}")]
4242
NoPreimageKeyFoundInPrecompile(Box<Error>),
43+
#[error("UnexpectedBlobKey: blob_key={0:?}")]
44+
UnexpectedBlobKey(Vec<u8>),
4345
#[error("UnexpectedSliceLength: {0} {1}")]
4446
UnexpectedSliceLength(usize, usize),
4547
#[error("OracleProviderError: err={0:?}")]
@@ -48,4 +50,6 @@ pub enum Error {
4850
DriverError(#[from] kona_driver::DriverError<kona_executor::ExecutorError>),
4951
#[error("PipelineError: err={0:?}")]
5052
PipelineError(#[from] kona_derive::errors::PipelineErrorKind),
53+
#[error("UnexpectedBlobSidecarLength: size={0}")]
54+
UnexpectedBlobSidecarLength(usize),
5155
}

derivation/src/oracle.rs

Lines changed: 88 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ use kona_proof::l1::ROOTS_OF_UNITY;
1717
use kona_proof::FlushableCache;
1818
use sha2::{Digest, Sha256};
1919

20+
const SIDECAR_BLOB_SIZE: usize = 32;
21+
2022
#[derive(Clone, Debug, Default)]
2123
pub struct MemoryOracleClient {
2224
/// Avoid deepcopy by clone operation because the preimage size is so big.
@@ -104,9 +106,9 @@ impl TryFrom<Vec<Preimage>> for MemoryOracleClient {
104106

105107
// Ensure blob preimage is valid
106108
let mut kzg_cache = HashSet::<Vec<u8>>::new();
107-
for (key, data) in inner.iter() {
109+
for (key, _) in inner.iter() {
108110
if key.key_type() == PreimageKeyType::Blob {
109-
verify_blob_preimage(key, data, &inner, &mut kzg_cache)?
111+
verify_blob_preimage(key, &inner, &mut kzg_cache)?
110112
} else if key.key_type() == PreimageKeyType::Precompile {
111113
verify_precompile(key, &inner)?
112114
}
@@ -169,12 +171,14 @@ fn verify_keccak256_preimage(key: &PreimageKey, data: &[u8]) -> Result<(), Error
169171

170172
fn verify_blob_preimage(
171173
key: &PreimageKey,
172-
data: &[u8],
173174
preimages: &HashMap<PreimageKey, Vec<u8>>,
174175
kzg_cache: &mut HashSet<Vec<u8>>,
175176
) -> Result<(), Error> {
176177
let blob_key = get_data_by_hash_key(key, preimages)
177178
.map_err(|e| Error::NoPreimageKeyFoundInVerifyBlob(Box::new(e)))?;
179+
if blob_key.len() != POSITION_FIELD_ELEMENT + 8 {
180+
return Err(Error::UnexpectedBlobKey(blob_key.to_vec()));
181+
}
178182
let kzg_commitment = &blob_key[..BYTES_PER_COMMITMENT];
179183
if kzg_cache.contains(kzg_commitment) {
180184
return Ok(());
@@ -193,24 +197,19 @@ fn verify_blob_preimage(
193197
.as_ref(),
194198
)?;
195199
let sidecar_blob = get_data_by_blob_key(blob_key, preimages)?;
200+
if sidecar_blob.len() != SIDECAR_BLOB_SIZE {
201+
return Err(Error::UnexpectedBlobSidecarLength(sidecar_blob.len()));
202+
}
196203
blob[(i as usize) << 5..(i as usize + 1) << 5].copy_from_slice(sidecar_blob);
197204
}
198205

199206
// Require kzg_proof data to verify all the blob index
200207
let kzg_proof = {
201-
let field_element_index: [u8; 8] = blob_key[POSITION_FIELD_ELEMENT..]
202-
.try_into()
203-
.map_err(Error::UnexpectedBlobFieldIndex)?;
204-
if u64::from_be_bytes(field_element_index) == FIELD_ELEMENTS_PER_BLOB {
205-
data
206-
} else {
207-
// Get by 4096 index
208-
let slice = &mut blob_key[POSITION_FIELD_ELEMENT..];
209-
try_copy_slice(slice, FIELD_ELEMENTS_PER_BLOB.to_be_bytes().as_ref())?;
210-
get_data_by_blob_key(blob_key, preimages).map_err(|e| {
211-
Error::NoPreimageDataFoundInVerifyBlob(blob_key.to_vec(), Box::new(e))
212-
})?
213-
}
208+
// Get by 4096 index
209+
let slice = &mut blob_key[POSITION_FIELD_ELEMENT..];
210+
try_copy_slice(slice, FIELD_ELEMENTS_PER_BLOB.to_be_bytes().as_ref())?;
211+
get_data_by_blob_key(blob_key, preimages)
212+
.map_err(|e| Error::NoPreimageDataFoundInVerifyBlob(blob_key.to_vec(), Box::new(e)))?
214213
};
215214
// Ensure valida blob
216215
let kzg_blob = kzg_rs::Blob::from_slice(&blob).map_err(Error::UnexpectedKZGBlob)?;
@@ -251,7 +250,9 @@ fn try_copy_slice(slice: &mut [u8], value: &[u8]) -> Result<(), Error> {
251250
#[cfg(test)]
252251
mod test {
253252
use crate::errors::Error;
254-
use crate::oracle::{try_copy_slice, verify_blob_preimage, MemoryOracleClient};
253+
use crate::oracle::{
254+
try_copy_slice, verify_blob_preimage, MemoryOracleClient, SIDECAR_BLOB_SIZE,
255+
};
255256
use crate::types::Preimage;
256257
use crate::POSITION_FIELD_ELEMENT;
257258
use alloc::vec;
@@ -328,6 +329,28 @@ mod test {
328329
}
329330
}
330331

332+
#[test]
333+
fn test_try_from_invalid_blob_key_error() {
334+
let blob_key = [0u8; POSITION_FIELD_ELEMENT + 7];
335+
let blob_key_hash = keccak256(blob_key);
336+
let preimage = vec![
337+
Preimage::new(
338+
PreimageKey::new(*blob_key_hash, PreimageKeyType::Keccak256),
339+
blob_key.to_vec(),
340+
),
341+
Preimage::new(
342+
PreimageKey::new(*blob_key_hash, PreimageKeyType::Blob),
343+
vec![].to_vec(),
344+
),
345+
];
346+
347+
let err = MemoryOracleClient::try_from(preimage).unwrap_err();
348+
match err {
349+
Error::UnexpectedBlobKey(_) => {}
350+
_ => panic!("Unexpected error, got: {:?}", err),
351+
}
352+
}
353+
331354
#[test]
332355
fn test_try_from_blob_no_kzg_proof_error() {
333356
let mut blob_key = [0u8; POSITION_FIELD_ELEMENT + 8];
@@ -356,7 +379,7 @@ mod test {
356379

357380
let first_key = PreimageKey::new(*blob_key_hash, PreimageKeyType::Blob);
358381
let mut cache = HashSet::new();
359-
let err = verify_blob_preimage(&first_key, &[0u8; 10], &preimages, &mut cache).unwrap_err();
382+
let err = verify_blob_preimage(&first_key, &preimages, &mut cache).unwrap_err();
360383
match err {
361384
Error::NoPreimageDataFoundInVerifyBlob(_, _) => {}
362385
_ => panic!("Unexpected error, got: {:?}", err),
@@ -400,13 +423,59 @@ mod test {
400423

401424
let first_key = PreimageKey::new(*blob_key_hash, PreimageKeyType::Blob);
402425
let mut cache = HashSet::new();
403-
let err = verify_blob_preimage(&first_key, &[0u8; 10], &preimages, &mut cache).unwrap_err();
426+
let err = verify_blob_preimage(&first_key, &preimages, &mut cache).unwrap_err();
404427
match err {
405428
Error::UnexpectedPreimageBlob(_) => {}
406429
_ => panic!("Unexpected error, got: {:?}", err),
407430
}
408431
}
409432

433+
#[test]
434+
fn test_verify_blob_preimage_error_invalid_sidecar() {
435+
let mut blob_key = [0u8; POSITION_FIELD_ELEMENT + 8];
436+
let mut preimages = HashMap::new();
437+
438+
for i in 0..FIELD_ELEMENTS_PER_BLOB {
439+
blob_key[BYTES_PER_COMMITMENT..].copy_from_slice(
440+
ROOTS_OF_UNITY[i as usize]
441+
.into_bigint()
442+
.to_bytes_be()
443+
.as_ref(),
444+
);
445+
let blob_per_index_key = keccak256(blob_key);
446+
let sidecar_blob = [0u8; SIDECAR_BLOB_SIZE - 1].to_vec();
447+
preimages.insert(
448+
PreimageKey::new(*blob_per_index_key, PreimageKeyType::Blob),
449+
sidecar_blob,
450+
);
451+
}
452+
453+
let blob_key_hash = keccak256(blob_key);
454+
let mut final_kzg_proof_key = blob_key;
455+
final_kzg_proof_key[POSITION_FIELD_ELEMENT..]
456+
.copy_from_slice((FIELD_ELEMENTS_PER_BLOB).to_be_bytes().as_ref());
457+
let final_kzg_proof = [0u8; BYTES_PER_COMMITMENT];
458+
let kzg_proof_key_hash = keccak256(final_kzg_proof_key);
459+
preimages.insert(
460+
PreimageKey::new(*blob_key_hash, PreimageKeyType::Keccak256),
461+
blob_key.to_vec(),
462+
);
463+
preimages.insert(
464+
PreimageKey::new(*kzg_proof_key_hash, PreimageKeyType::Blob),
465+
final_kzg_proof.to_vec(),
466+
);
467+
468+
let first_key = PreimageKey::new(*blob_key_hash, PreimageKeyType::Blob);
469+
let mut cache = HashSet::new();
470+
let err = verify_blob_preimage(&first_key, &preimages, &mut cache).unwrap_err();
471+
match err {
472+
Error::UnexpectedBlobSidecarLength(size) => {
473+
assert_eq!(size, SIDECAR_BLOB_SIZE - 1);
474+
}
475+
_ => panic!("Unexpected error, got: {:?}", err),
476+
}
477+
}
478+
410479
#[test]
411480
fn test_copy_slice_error() {
412481
let mut slice = [0u8; 4];

0 commit comments

Comments
 (0)