Skip to content

Commit

Permalink
add transformation function
Browse files Browse the repository at this point in the history
  • Loading branch information
kariy committed Sep 25, 2024
1 parent 7da7c00 commit 07ddee3
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 3 deletions.
14 changes: 13 additions & 1 deletion crates/katana/primitives/src/da/blob.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use num_bigint::BigUint;
use num_traits::Num;

use super::eip4844::{BLOB_LEN, BLS_MODULUS, GENERATOR};
use super::math::ifft;
use super::math::{fft, ifft};

/// Recovers the original data from a given blob.
///
Expand All @@ -27,3 +27,15 @@ pub fn recover(data: Vec<BigUint>) -> Vec<BigUint> {

ifft(data, xs, &BLS_MODULUS)
}

pub fn transform(data: Vec<BigUint>) -> Vec<BigUint> {
let xs: Vec<BigUint> = (0..BLOB_LEN)
.map(|i| {
let bin = format!("{:012b}", i);
let bin_rev = bin.chars().rev().collect::<String>();
GENERATOR.modpow(&BigUint::from_str_radix(&bin_rev, 2).unwrap(), &BLS_MODULUS)
})
.collect();

fft(data, xs, &BLS_MODULUS)
}
16 changes: 16 additions & 0 deletions crates/katana/primitives/src/da/math.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,22 @@ lazy_static! {
pub static ref TWO: BigUint = 2u32.to_biguint().unwrap();
}

pub fn fft(elements: Vec<BigUint>, xs: Vec<BigUint>, p: &BigUint) -> Vec<BigUint> {
let n = elements.len();
let mut transform = vec![BigUint::ZERO; n];

for i in 0..n {
for j in (0..n).rev() {
let value = &transform[i] * &xs[i];
let value = value + &elements[j];
let value = value % p;
transform[i] = value;
}
}

transform
}

/// Performs the inverse Fast Fourier Transform on a vector of `BigUint`.
///
/// # Arguments
Expand Down
22 changes: 20 additions & 2 deletions crates/katana/primitives/tests/blobs.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use anyhow::Result;
use katana_primitives::da::eip4844::BLOB_LEN;
use katana_primitives::da::encoding::encode_state_updates;
use katana_primitives::da::serde::parse_str_to_blob_data;
use katana_primitives::da::{blob, encoding};
Expand All @@ -17,8 +18,25 @@ fn read(path: &str) -> Vec<BigUint> {
#[case("./tests/test-data/blobs/block_636263.txt")]
#[case("./tests/test-data/blobs/block_636264.txt")]
fn parse_blobs_rt(#[case] blob: &str) -> Result<()> {
let encoded = blob::recover(read(blob));
// the fft'd version
let fftd = read(blob);
// the ifft'd version
let encoded = blob::recover(fftd.clone());

let state_update = encoding::decode_state_updates(&encoded)?;
let _ = encode_state_updates(state_update);
let mut reencoded = encode_state_updates(state_update);

// TODO: put this directly in the encoding module
while reencoded.len() < BLOB_LEN {
reencoded.push(BigUint::ZERO);
}

// re-fft the reencoded data
let refftd = blob::transform(reencoded.clone());

// assert that our encoding and transformation functions are correct
similar_asserts::assert_eq!(encoded, reencoded);
similar_asserts::assert_eq!(fftd, refftd);

Ok(())
}

0 comments on commit 07ddee3

Please sign in to comment.