Skip to content

Commit ab48c63

Browse files
authored
Merge pull request #10 from datachainlab/feature/blobkey-suffix-check
DAT-9: Add verification of blob key suffixes
2 parents b075c19 + 1cf709b commit ab48c63

File tree

2 files changed

+90
-11
lines changed

2 files changed

+90
-11
lines changed

derivation/src/errors.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ pub enum Error {
2323
UnexpectedPreimageBlobResult(PreimageKey),
2424
#[error("UnexpectedBlobFieldIndex: err={0:?}")]
2525
UnexpectedBlobFieldIndex(TryFromSliceError),
26+
#[error("UnexpectedBlobKeySuffix: blobKey={0:?}")]
27+
UnexpectedBlobKeySuffix(Vec<u8>),
2628
#[error("UnexpectedPreimageKeySize: size={0}")]
2729
UnexpectedPreimageKeySize(usize),
2830
#[error("UnexpectedPreimageKey: err={source:?} key={key:?}")]

derivation/src/oracle.rs

Lines changed: 88 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,29 @@ impl HintWriterClient for MemoryOracleClient {
7878
}
7979
}
8080

81+
fn generate_valid_suffixes() -> (HashSet<Vec<u8>>, Vec<Vec<u8>>) {
82+
let mut valid_suffixes = HashSet::<Vec<u8>>::with_capacity(FIELD_ELEMENTS_PER_BLOB as usize);
83+
let mut roots_of_unity = Vec::<Vec<u8>>::with_capacity(FIELD_ELEMENTS_PER_BLOB as usize);
84+
85+
for i in 0..FIELD_ELEMENTS_PER_BLOB {
86+
let blob_suffix = ROOTS_OF_UNITY[i as usize].into_bigint().to_bytes_be();
87+
roots_of_unity.push(blob_suffix.clone());
88+
valid_suffixes.insert(blob_suffix);
89+
}
90+
91+
let proof_suffix = {
92+
let mut last_root_of_unity = ROOTS_OF_UNITY[FIELD_ELEMENTS_PER_BLOB as usize - 1]
93+
.into_bigint()
94+
.to_bytes_be();
95+
last_root_of_unity[(POSITION_FIELD_ELEMENT - BYTES_PER_COMMITMENT)..]
96+
.copy_from_slice(&FIELD_ELEMENTS_PER_BLOB.to_be_bytes());
97+
last_root_of_unity
98+
};
99+
valid_suffixes.insert(proof_suffix);
100+
101+
(valid_suffixes, roots_of_unity)
102+
}
103+
81104
impl TryFrom<Vec<Preimage>> for MemoryOracleClient {
82105
type Error = Error;
83106

@@ -107,10 +130,18 @@ impl TryFrom<Vec<Preimage>> for MemoryOracleClient {
107130
}
108131

109132
// Ensure blob preimage is valid
133+
let (valid_suffixes, roots_of_unity) = generate_valid_suffixes();
110134
let mut kzg_cache = HashSet::<Vec<u8>>::new();
111135
for (key, data) in inner.iter() {
112136
if key.key_type() == PreimageKeyType::Blob {
113-
verify_blob_preimage(key, data, &inner, &mut kzg_cache)?
137+
verify_blob_preimage(
138+
key,
139+
data,
140+
&inner,
141+
&mut kzg_cache,
142+
&valid_suffixes,
143+
&roots_of_unity,
144+
)?
114145
} else if key.key_type() == PreimageKeyType::Precompile {
115146
verify_precompile(key, &inner)?
116147
}
@@ -176,9 +207,14 @@ fn verify_blob_preimage(
176207
data: &[u8],
177208
preimages: &HashMap<PreimageKey, Vec<u8>>,
178209
kzg_cache: &mut HashSet<Vec<u8>>,
210+
valid_suffixes: &HashSet<Vec<u8>>,
211+
roots_of_unity: &[Vec<u8>],
179212
) -> Result<(), Error> {
180213
let blob_key = get_data_by_hash_key(key, preimages)
181214
.map_err(|e| Error::NoPreimageKeyFoundInVerifyBlob(Box::new(e)))?;
215+
if !valid_suffixes.contains(&blob_key[BYTES_PER_COMMITMENT..]) {
216+
return Err(Error::UnexpectedBlobKeySuffix(blob_key.to_vec()));
217+
}
182218
let kzg_commitment = &blob_key[..BYTES_PER_COMMITMENT];
183219
if kzg_cache.contains(kzg_commitment) {
184220
return Ok(());
@@ -189,13 +225,7 @@ fn verify_blob_preimage(
189225
let mut blob = [0u8; kzg_rs::BYTES_PER_BLOB];
190226
for i in 0..FIELD_ELEMENTS_PER_BLOB {
191227
let slice = &mut blob_key[BYTES_PER_COMMITMENT..];
192-
try_copy_slice(
193-
slice,
194-
ROOTS_OF_UNITY[i as usize]
195-
.into_bigint()
196-
.to_bytes_be()
197-
.as_ref(),
198-
)?;
228+
try_copy_slice(slice, roots_of_unity[i as usize].as_ref())?;
199229
let sidecar_blob = get_data_by_blob_key(blob_key, preimages)?;
200230
blob[(i as usize) << 5..(i as usize + 1) << 5].copy_from_slice(sidecar_blob);
201231
}
@@ -255,7 +285,9 @@ fn try_copy_slice(slice: &mut [u8], value: &[u8]) -> Result<(), Error> {
255285
#[cfg(test)]
256286
mod test {
257287
use crate::errors::Error;
258-
use crate::oracle::{try_copy_slice, verify_blob_preimage, MemoryOracleClient};
288+
use crate::oracle::{
289+
generate_valid_suffixes, try_copy_slice, verify_blob_preimage, MemoryOracleClient,
290+
};
259291
use crate::types::Preimage;
260292
use crate::POSITION_FIELD_ELEMENT;
261293
use alloc::vec;
@@ -378,8 +410,17 @@ mod test {
378410
);
379411

380412
let first_key = PreimageKey::new(*blob_key_hash, PreimageKeyType::Blob);
413+
let (valid_suffixes, roots_of_unity) = generate_valid_suffixes();
381414
let mut cache = HashSet::new();
382-
let err = verify_blob_preimage(&first_key, &[0u8; 10], &preimages, &mut cache).unwrap_err();
415+
let err = verify_blob_preimage(
416+
&first_key,
417+
&[0u8; 10],
418+
&preimages,
419+
&mut cache,
420+
&valid_suffixes,
421+
&roots_of_unity,
422+
)
423+
.unwrap_err();
383424
match err {
384425
Error::NoPreimageDataFoundInVerifyBlob(_, _) => {}
385426
_ => panic!("Unexpected error, got: {:?}", err),
@@ -422,8 +463,17 @@ mod test {
422463
);
423464

424465
let first_key = PreimageKey::new(*blob_key_hash, PreimageKeyType::Blob);
466+
let (valid_suffixes, roots_of_unity) = generate_valid_suffixes();
425467
let mut cache = HashSet::new();
426-
let err = verify_blob_preimage(&first_key, &[0u8; 10], &preimages, &mut cache).unwrap_err();
468+
let err = verify_blob_preimage(
469+
&first_key,
470+
&[0u8; 10],
471+
&preimages,
472+
&mut cache,
473+
&valid_suffixes,
474+
&roots_of_unity,
475+
)
476+
.unwrap_err();
427477
match err {
428478
Error::UnexpectedPreimageBlob(_) => {}
429479
_ => panic!("Unexpected error, got: {:?}", err),
@@ -440,4 +490,31 @@ mod test {
440490
_ => panic!("Unexpected error, got: {:?}", err),
441491
}
442492
}
493+
494+
#[test]
495+
fn test_try_from_blob_key_suffix_error() {
496+
let blob_key = [0u8; POSITION_FIELD_ELEMENT + 8];
497+
let blob_key_hash = keccak256(blob_key);
498+
let mut preimages = HashMap::new();
499+
preimages.insert(
500+
PreimageKey::new(*blob_key_hash, PreimageKeyType::Keccak256),
501+
blob_key.to_vec(),
502+
);
503+
504+
let (valid_suffixes, roots_of_unity) = generate_valid_suffixes();
505+
let mut cache = HashSet::new();
506+
let err = verify_blob_preimage(
507+
&PreimageKey::new(*blob_key_hash, PreimageKeyType::Blob),
508+
&[0u8; 10],
509+
&preimages,
510+
&mut cache,
511+
&valid_suffixes,
512+
&roots_of_unity,
513+
)
514+
.unwrap_err();
515+
match err {
516+
Error::UnexpectedBlobKeySuffix(_) => {}
517+
_ => panic!("Unexpected error, got: {:?}", err),
518+
}
519+
}
443520
}

0 commit comments

Comments
 (0)