Skip to content

Commit

Permalink
Merge pull request #19 from AlexShukel/implement-eip-7594-constantine
Browse files Browse the repository at this point in the history
Implemented eip_7594 in constantine crate
  • Loading branch information
ArtiomTr authored Oct 12, 2024
2 parents e1919d4 + b413d31 commit 1376c8b
Show file tree
Hide file tree
Showing 24 changed files with 788 additions and 235 deletions.
2 changes: 1 addition & 1 deletion blst/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ pub(crate) fn fft_settings_to_rust(

Ok(FsFFTSettings {
max_width: FIELD_ELEMENTS_PER_EXT_BLOB,
root_of_unity: roots_of_unity[0],
root_of_unity: roots_of_unity[1],
roots_of_unity,
brp_roots_of_unity,
reverse_roots_of_unity,
Expand Down
5 changes: 2 additions & 3 deletions constantine/benches/eip_4844.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use criterion::{criterion_group, criterion_main, Criterion};
use kzg::eip_4844::{
blob_to_kzg_commitment_rust, bytes_to_blob, compute_blob_kzg_proof_rust,
compute_cells_and_kzg_proofs_rust, compute_kzg_proof_rust, verify_blob_kzg_proof_batch_rust,
verify_blob_kzg_proof_rust, verify_kzg_proof_rust,
compute_kzg_proof_rust, verify_blob_kzg_proof_batch_rust, verify_blob_kzg_proof_rust,
verify_kzg_proof_rust,
};
use kzg_bench::benches::eip_4844::bench_eip_4844;
use rust_kzg_constantine::{
Expand All @@ -27,7 +27,6 @@ fn bench_eip_4844_(c: &mut Criterion) {
&compute_kzg_proof_rust,
&verify_kzg_proof_rust,
&compute_blob_kzg_proof_rust,
&compute_cells_and_kzg_proofs_rust,
&verify_blob_kzg_proof_rust,
&verify_blob_kzg_proof_batch_rust,
);
Expand Down
4 changes: 2 additions & 2 deletions constantine/src/data_availability_sampling.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ impl CtFFTSettings {
Ordering::Equal => {
let x = evens[0].add(&evens[1]);
let y = evens[0].sub(&evens[1]);
let y_times_root = y.mul(&self.expanded_roots_of_unity[stride]);
let y_times_root = y.mul(&self.roots_of_unity[stride]);

evens[0] = x.add(&y_times_root);
evens[1] = x.sub(&y_times_root);
Expand Down Expand Up @@ -64,7 +64,7 @@ impl CtFFTSettings {
for i in 0..half {
let x = evens[i];
let y = evens[half + i];
let y_times_root: CtFr = y.mul(&self.expanded_roots_of_unity[(1 + 2 * i) * stride]);
let y_times_root: CtFr = y.mul(&self.roots_of_unity[(1 + 2 * i) * stride]);

evens[i] = x.add(&y_times_root);
evens[half + i] = x.sub(&y_times_root);
Expand Down
244 changes: 99 additions & 145 deletions constantine/src/eip_4844.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@ extern crate alloc;
use alloc::boxed::Box;
use alloc::string::String;
use alloc::vec::Vec;
use core::ptr::null_mut;
use kzg::common_utils::reverse_bit_order;
use core::ptr::{self};
use kzg::eip_4844::{
blob_to_kzg_commitment_rust, compute_blob_kzg_proof_rust, compute_kzg_proof_rust,
load_trusted_setup_rust, verify_blob_kzg_proof_batch_rust, verify_blob_kzg_proof_rust,
verify_kzg_proof_rust,
verify_kzg_proof_rust, FIELD_ELEMENTS_PER_CELL, FIELD_ELEMENTS_PER_EXT_BLOB,
};
use kzg::{cfg_into_iter, Fr, G1};
#[cfg(feature = "std")]
Expand All @@ -23,18 +22,15 @@ use kzg::eip_4844::load_trusted_setup_string;

use kzg::eip_4844::{
Blob, Bytes32, Bytes48, CKZGSettings, KZGCommitment, KZGProof, PrecomputationTableManager,
BYTES_PER_FIELD_ELEMENT, BYTES_PER_G1, BYTES_PER_G2, C_KZG_RET, C_KZG_RET_BADARGS,
C_KZG_RET_OK, FIELD_ELEMENTS_PER_BLOB, TRUSTED_SETUP_NUM_G1_POINTS,
TRUSTED_SETUP_NUM_G2_POINTS,
BYTES_PER_G1, C_KZG_RET, C_KZG_RET_BADARGS, C_KZG_RET_OK, FIELD_ELEMENTS_PER_BLOB,
TRUSTED_SETUP_NUM_G1_POINTS, TRUSTED_SETUP_NUM_G2_POINTS,
};

use crate::types::fft_settings::CtFFTSettings;
use crate::types::fp::CtFp;
use crate::types::fr::CtFr;
use crate::types::g1::{CtG1, CtG1Affine};

use crate::types::g2::CtG2;
use crate::types::kzg_settings::CtKZGSettings;
use crate::utils::{deserialize_blob, kzg_settings_to_c, kzg_settings_to_rust};

#[cfg(feature = "parallel")]
use rayon::prelude::*;
Expand All @@ -43,111 +39,17 @@ static mut PRECOMPUTATION_TABLES: PrecomputationTableManager<CtFr, CtG1, CtFp, C
PrecomputationTableManager::new();

#[cfg(feature = "std")]
pub fn load_trusted_setup_filename_rust(filepath: &str) -> Result<CtKZGSettings, String> {
pub fn load_trusted_setup_filename_rust(
filepath: &str,
) -> Result<crate::types::kzg_settings::CtKZGSettings, alloc::string::String> {
let mut file = File::open(filepath).map_err(|_| "Unable to open file".to_string())?;
let mut contents = String::new();
file.read_to_string(&mut contents)
.map_err(|_| "Unable to read file".to_string())?;

let (g1_bytes, g2_bytes) = load_trusted_setup_string(&contents)?;
load_trusted_setup_rust(g1_bytes.as_slice(), g2_bytes.as_slice())
}

fn fft_settings_to_rust(c_settings: *const CKZGSettings) -> Result<CtFFTSettings, String> {
let settings = unsafe { &*c_settings };

let roots_of_unity = unsafe {
core::slice::from_raw_parts(settings.roots_of_unity, settings.max_width as usize)
.iter()
.map(|r| CtFr::from_blst_fr(*r))
.collect::<Vec<CtFr>>()
};
let mut expanded_roots_of_unity = roots_of_unity.clone();
reverse_bit_order(&mut expanded_roots_of_unity)?;
expanded_roots_of_unity.push(CtFr::one());
let mut reverse_roots_of_unity = expanded_roots_of_unity.clone();
reverse_roots_of_unity.reverse();

let mut first_root = expanded_roots_of_unity[1];
let first_root_arr = [first_root; 1];
first_root = first_root_arr[0];

Ok(CtFFTSettings {
max_width: settings.max_width as usize,
root_of_unity: first_root,
expanded_roots_of_unity,
reverse_roots_of_unity,
roots_of_unity,
})
}

fn kzg_settings_to_rust(c_settings: &CKZGSettings) -> Result<CtKZGSettings, String> {
let secret_g1 = unsafe {
core::slice::from_raw_parts(c_settings.g1_values, TRUSTED_SETUP_NUM_G1_POINTS)
.iter()
.map(|r| CtG1::from_blst_p1(*r))
.collect::<Vec<CtG1>>()
};
Ok(CtKZGSettings {
fs: fft_settings_to_rust(c_settings)?,
secret_g1,
secret_g2: unsafe {
core::slice::from_raw_parts(c_settings.g2_values, TRUSTED_SETUP_NUM_G2_POINTS)
.iter()
.map(|r| CtG2::from_blst_p2(*r))
.collect::<Vec<CtG2>>()
},
precomputation: None,
})
}

fn kzg_settings_to_c(rust_settings: &CtKZGSettings) -> CKZGSettings {
let g1_val = rust_settings
.secret_g1
.iter()
.map(|r| r.to_blst_p1())
.collect::<Vec<blst::blst_p1>>();
let g1_val = Box::new(g1_val);
let g2_val = rust_settings
.secret_g2
.iter()
.map(|r| r.to_blst_p2())
.collect::<Vec<blst::blst_p2>>();
let x = g2_val.into_boxed_slice();
let stat_ref = Box::leak(x);
let v = Box::into_raw(g1_val);

let roots_of_unity = Box::new(
rust_settings
.fs
.roots_of_unity
.iter()
.map(|r| r.to_blst_fr())
.collect::<Vec<blst::blst_fr>>(),
);

CKZGSettings {
max_width: rust_settings.fs.max_width as u64,
roots_of_unity: unsafe { (*Box::into_raw(roots_of_unity)).as_mut_ptr() },
g1_values: unsafe { (*v).as_mut_ptr() },
g2_values: stat_ref.as_mut_ptr(),
}
}

unsafe fn deserialize_blob(blob: *const Blob) -> Result<Vec<CtFr>, C_KZG_RET> {
(*blob)
.bytes
.chunks(BYTES_PER_FIELD_ELEMENT)
.map(|chunk| {
let mut bytes = [0u8; BYTES_PER_FIELD_ELEMENT];
bytes.copy_from_slice(chunk);
if let Ok(result) = CtFr::from_bytes(&bytes) {
Ok(result)
} else {
Err(C_KZG_RET_BADARGS)
}
})
.collect::<Result<Vec<CtFr>, C_KZG_RET>>()
let (g1_monomial_bytes, g1_lagrange_bytes, g2_monomial_bytes) =
load_trusted_setup_string(&contents)?;
load_trusted_setup_rust(&g1_monomial_bytes, &g1_lagrange_bytes, &g2_monomial_bytes)
}

macro_rules! handle_ckzg_badargs {
Expand Down Expand Up @@ -183,22 +85,32 @@ pub unsafe extern "C" fn blob_to_kzg_commitment(
#[no_mangle]
pub unsafe extern "C" fn load_trusted_setup(
out: *mut CKZGSettings,
g1_bytes: *const u8,
n1: usize,
g2_bytes: *const u8,
n2: usize,
g1_monomial_bytes: *const u8,
num_g1_monomial_bytes: u64,
g1_lagrange_bytes: *const u8,
num_g1_lagrange_bytes: u64,
g2_monomial_bytes: *const u8,
num_g2_monomial_bytes: u64,
_precompute: u64,
) -> C_KZG_RET {
let g1_bytes = core::slice::from_raw_parts(g1_bytes, n1 * BYTES_PER_G1);
let g2_bytes = core::slice::from_raw_parts(g2_bytes, n2 * BYTES_PER_G2);
TRUSTED_SETUP_NUM_G1_POINTS = g1_bytes.len() / BYTES_PER_G1;
let mut settings = handle_ckzg_badargs!(load_trusted_setup_rust(g1_bytes, g2_bytes));
let g1_monomial_bytes =
core::slice::from_raw_parts(g1_monomial_bytes, num_g1_monomial_bytes as usize);
let g1_lagrange_bytes =
core::slice::from_raw_parts(g1_lagrange_bytes, num_g1_lagrange_bytes as usize);
let g2_monomial_bytes =
core::slice::from_raw_parts(g2_monomial_bytes, num_g2_monomial_bytes as usize);
TRUSTED_SETUP_NUM_G1_POINTS = num_g1_monomial_bytes as usize / BYTES_PER_G1;
let mut settings = handle_ckzg_badargs!(load_trusted_setup_rust(
g1_monomial_bytes,
g1_lagrange_bytes,
g2_monomial_bytes
));

let c_settings = kzg_settings_to_c(&settings);

PRECOMPUTATION_TABLES.save_precomputation(settings.precomputation.take(), &c_settings);

*out = c_settings;

C_KZG_RET_OK
}

Expand All @@ -212,17 +124,19 @@ pub unsafe extern "C" fn load_trusted_setup_file(
let mut buf = vec![0u8; 1024 * 1024];
let len: usize = libc::fread(buf.as_mut_ptr() as *mut libc::c_void, 1, buf.len(), in_);
let s = handle_ckzg_badargs!(String::from_utf8(buf[..len].to_vec()));
let (g1_bytes, g2_bytes) = handle_ckzg_badargs!(load_trusted_setup_string(&s));
TRUSTED_SETUP_NUM_G1_POINTS = g1_bytes.len() / BYTES_PER_G1;
let (g1_monomial_bytes, g1_lagrange_bytes, g2_monomial_bytes) =
handle_ckzg_badargs!(load_trusted_setup_string(&s));
TRUSTED_SETUP_NUM_G1_POINTS = g1_monomial_bytes.len() / BYTES_PER_G1;
if TRUSTED_SETUP_NUM_G1_POINTS != FIELD_ELEMENTS_PER_BLOB {
// Helps pass the Java test "shouldThrowExceptionOnIncorrectTrustedSetupFromFile",
// as well as 5 others that pass only if this one passes (likely because Java doesn't
// deallocate its KZGSettings pointer when no exception is thrown).
return C_KZG_RET_BADARGS;
}
let mut settings = handle_ckzg_badargs!(load_trusted_setup_rust(
g1_bytes.as_slice(),
g2_bytes.as_slice()
&g1_monomial_bytes,
&g1_lagrange_bytes,
&g2_monomial_bytes
));

let c_settings = kzg_settings_to_c(&settings);
Expand Down Expand Up @@ -266,30 +180,70 @@ pub unsafe extern "C" fn free_trusted_setup(s: *mut CKZGSettings) {
return;
}

PRECOMPUTATION_TABLES.remove_precomputation(&*s);
if !(*s).g1_values_monomial.is_null() {
let v = Box::from_raw(core::slice::from_raw_parts_mut(
(*s).g1_values_monomial,
FIELD_ELEMENTS_PER_BLOB,
));
drop(v);
(*s).g1_values_monomial = ptr::null_mut();
}

let max_width = (*s).max_width as usize;
let roots = Box::from_raw(core::slice::from_raw_parts_mut(
(*s).roots_of_unity,
max_width,
));
drop(roots);
(*s).roots_of_unity = null_mut();
if !(*s).g1_values_lagrange_brp.is_null() {
let v = Box::from_raw(core::slice::from_raw_parts_mut(
(*s).g1_values_lagrange_brp,
FIELD_ELEMENTS_PER_BLOB,
));
drop(v);
(*s).g1_values_lagrange_brp = ptr::null_mut();
}

let g1 = Box::from_raw(core::slice::from_raw_parts_mut(
(*s).g1_values,
TRUSTED_SETUP_NUM_G1_POINTS,
));
drop(g1);
(*s).g1_values = null_mut();
if !(*s).g2_values_monomial.is_null() {
let v = Box::from_raw(core::slice::from_raw_parts_mut(
(*s).g2_values_monomial,
TRUSTED_SETUP_NUM_G2_POINTS,
));
drop(v);
(*s).g2_values_monomial = ptr::null_mut();
}

let g2 = Box::from_raw(core::slice::from_raw_parts_mut(
(*s).g2_values,
TRUSTED_SETUP_NUM_G2_POINTS,
));
drop(g2);
(*s).g2_values = null_mut();
(*s).max_width = 0;
if !(*s).x_ext_fft_columns.is_null() {
let v = Box::from_raw(core::slice::from_raw_parts_mut(
(*s).x_ext_fft_columns,
2 * ((FIELD_ELEMENTS_PER_EXT_BLOB / 2) / FIELD_ELEMENTS_PER_CELL),
));
drop(v);
(*s).x_ext_fft_columns = ptr::null_mut();
}

if !(*s).roots_of_unity.is_null() {
let v = Box::from_raw(core::slice::from_raw_parts_mut(
(*s).roots_of_unity,
FIELD_ELEMENTS_PER_EXT_BLOB + 1,
));
drop(v);
(*s).roots_of_unity = ptr::null_mut();
}

if !(*s).reverse_roots_of_unity.is_null() {
let v = Box::from_raw(core::slice::from_raw_parts_mut(
(*s).reverse_roots_of_unity,
FIELD_ELEMENTS_PER_EXT_BLOB + 1,
));
drop(v);
(*s).reverse_roots_of_unity = ptr::null_mut();
}

if !(*s).brp_roots_of_unity.is_null() {
let v = Box::from_raw(core::slice::from_raw_parts_mut(
(*s).brp_roots_of_unity,
FIELD_ELEMENTS_PER_EXT_BLOB,
));
drop(v);
(*s).brp_roots_of_unity = ptr::null_mut();
}

PRECOMPUTATION_TABLES.remove_precomputation(&*s);
}

/// # Safety
Expand Down Expand Up @@ -459,8 +413,8 @@ mod tests {
converted_settings.fs.roots_of_unity
);
assert_eq!(
settings.fs.expanded_roots_of_unity,
converted_settings.fs.expanded_roots_of_unity
settings.fs.brp_roots_of_unity,
converted_settings.fs.brp_roots_of_unity
);
assert_eq!(
settings.fs.reverse_roots_of_unity,
Expand Down
Loading

0 comments on commit 1376c8b

Please sign in to comment.