From 3aab3e2385607ca29f7487aadff0be03dc0c22a6 Mon Sep 17 00:00:00 2001 From: Maksim Jaroslavcevas Date: Thu, 5 Dec 2024 19:05:38 +0200 Subject: [PATCH] updated blast code inside mcl --- mcl/src/data_availability_sampling.rs | 4 +- mcl/src/eip_4844.rs | 89 ++++---- mcl/src/eip_7594.rs | 305 +++----------------------- mcl/src/kzg_proofs.rs | 46 +++- mcl/src/types/kzg_settings.rs | 171 +++++++++++---- mcl/src/utils.rs | 96 +------- mcl/tests/eip_7594.rs | 128 ++++------- mcl/tests/fk20_proofs.rs | 86 +------- mcl/tests/kzg_proofs.rs | 100 ++++++--- 9 files changed, 370 insertions(+), 655 deletions(-) diff --git a/mcl/src/data_availability_sampling.rs b/mcl/src/data_availability_sampling.rs index 56a772026..4ee26fc86 100644 --- a/mcl/src/data_availability_sampling.rs +++ b/mcl/src/data_availability_sampling.rs @@ -4,7 +4,7 @@ use alloc::string::String; use alloc::vec::Vec; use core::cmp::Ordering; -use kzg::{Fr, DAS}; +use kzg::{DASExtension, Fr}; use crate::types::fft_settings::FsFFTSettings; use crate::types::fr::FsFr; @@ -71,7 +71,7 @@ impl FsFFTSettings { } } -impl DAS for FsFFTSettings { +impl DASExtension for FsFFTSettings { /// Polynomial extension for data availability sampling. Given values of even indices, produce values of odd indices. /// FFTSettings must hold at least 2 times the roots of provided evens. /// The resulting odd indices make the right half of the coefficients of the inverse FFT of the combined indices zero. diff --git a/mcl/src/eip_4844.rs b/mcl/src/eip_4844.rs index 8383826a3..da8bef5a1 100644 --- a/mcl/src/eip_4844.rs +++ b/mcl/src/eip_4844.rs @@ -6,8 +6,13 @@ use core::ptr; 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, FIELD_ELEMENTS_PER_CELL, FIELD_ELEMENTS_PER_EXT_BLOB, + verify_kzg_proof_rust, BYTES_PER_G1, FIELD_ELEMENTS_PER_BLOB, TRUSTED_SETUP_NUM_G1_POINTS, + TRUSTED_SETUP_NUM_G2_POINTS, +}; +use kzg::eth::c_bindings::{ + Blob, Bytes32, Bytes48, CKZGSettings, CKzgRet, KZGCommitment, KZGProof, }; +use kzg::eth::{FIELD_ELEMENTS_PER_CELL, FIELD_ELEMENTS_PER_EXT_BLOB}; use kzg::{cfg_into_iter, Fr, G1}; #[cfg(feature = "std")] use libc::FILE; @@ -19,18 +24,12 @@ use std::io::Read; #[cfg(feature = "std")] use kzg::eip_4844::load_trusted_setup_string; -use kzg::eip_4844::{ - Blob, Bytes32, Bytes48, CKZGSettings, KZGCommitment, KZGProof, 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::fr::FsFr; use crate::types::g1::FsG1; +use crate::types::kzg_settings::FsKZGSettings; use crate::utils::{ - deserialize_blob, handle_ckzg_badargs, kzg_settings_to_c, kzg_settings_to_rust, - PRECOMPUTATION_TABLES, + deserialize_blob, handle_ckzg_badargs, kzg_settings_to_c, PRECOMPUTATION_TABLES, }; #[cfg(feature = "parallel")] @@ -56,18 +55,18 @@ pub unsafe extern "C" fn blob_to_kzg_commitment( out: *mut KZGCommitment, blob: *const Blob, s: &CKZGSettings, -) -> C_KZG_RET { +) -> CKzgRet { if TRUSTED_SETUP_NUM_G1_POINTS == 0 { // FIXME: load_trusted_setup should set this value, but if not, it fails TRUSTED_SETUP_NUM_G1_POINTS = FIELD_ELEMENTS_PER_BLOB }; let deserialized_blob = handle_ckzg_badargs!(deserialize_blob(blob)); - let settings = handle_ckzg_badargs!(kzg_settings_to_rust(s)); + let settings: FsKZGSettings = handle_ckzg_badargs!(s.try_into()); let tmp = handle_ckzg_badargs!(blob_to_kzg_commitment_rust(&deserialized_blob, &settings)); (*out).bytes = tmp.to_bytes(); - C_KZG_RET_OK + CKzgRet::Ok } /// # Safety @@ -81,7 +80,7 @@ pub unsafe extern "C" fn load_trusted_setup( g2_monomial_bytes: *const u8, num_g2_monomial_bytes: u64, _precompute: u64, -) -> C_KZG_RET { +) -> CKzgRet { *out = CKZGSettings { brp_roots_of_unity: ptr::null_mut(), roots_of_unity: ptr::null_mut(), @@ -113,7 +112,7 @@ pub unsafe extern "C" fn load_trusted_setup( PRECOMPUTATION_TABLES.save_precomputation(settings.precomputation.take(), &c_settings); *out = c_settings; - C_KZG_RET_OK + CKzgRet::Ok } /// # Safety @@ -122,7 +121,7 @@ pub unsafe extern "C" fn load_trusted_setup( pub unsafe extern "C" fn load_trusted_setup_file( out: *mut CKZGSettings, in_: *mut FILE, -) -> C_KZG_RET { +) -> CKzgRet { *out = CKZGSettings { brp_roots_of_unity: ptr::null_mut(), roots_of_unity: ptr::null_mut(), @@ -146,7 +145,7 @@ pub unsafe extern "C" fn load_trusted_setup_file( // 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; + return CKzgRet::BadArgs; } let mut settings = handle_ckzg_badargs!(load_trusted_setup_rust( &g1_monomial_bytes, @@ -160,7 +159,7 @@ pub unsafe extern "C" fn load_trusted_setup_file( *out = c_settings; - C_KZG_RET_OK + CKzgRet::Ok } /// # Safety @@ -170,14 +169,14 @@ pub unsafe extern "C" fn compute_blob_kzg_proof( blob: *const Blob, commitment_bytes: *const Bytes48, s: &CKZGSettings, -) -> C_KZG_RET { +) -> CKzgRet { let deserialized_blob = match deserialize_blob(blob) { Ok(value) => value, Err(err) => return err, }; let commitment_g1 = handle_ckzg_badargs!(FsG1::from_bytes(&(*commitment_bytes).bytes)); - let settings = handle_ckzg_badargs!(kzg_settings_to_rust(s)); + let settings: FsKZGSettings = handle_ckzg_badargs!(s.try_into()); let proof = handle_ckzg_badargs!(compute_blob_kzg_proof_rust( &deserialized_blob, &commitment_g1, @@ -185,7 +184,7 @@ pub unsafe extern "C" fn compute_blob_kzg_proof( )); (*out).bytes = proof.to_bytes(); - C_KZG_RET_OK + CKzgRet::Ok } /// # Safety @@ -270,13 +269,13 @@ pub unsafe extern "C" fn verify_kzg_proof( y_bytes: *const Bytes32, proof_bytes: *const Bytes48, s: &CKZGSettings, -) -> C_KZG_RET { +) -> CKzgRet { let frz = handle_ckzg_badargs!(FsFr::from_bytes(&(*z_bytes).bytes)); let fry = handle_ckzg_badargs!(FsFr::from_bytes(&(*y_bytes).bytes)); let g1commitment = handle_ckzg_badargs!(FsG1::from_bytes(&(*commitment_bytes).bytes)); let g1proof = handle_ckzg_badargs!(FsG1::from_bytes(&(*proof_bytes).bytes)); - let settings = handle_ckzg_badargs!(kzg_settings_to_rust(s)); + let settings: FsKZGSettings = handle_ckzg_badargs!(s.try_into()); let result = handle_ckzg_badargs!(verify_kzg_proof_rust( &g1commitment, @@ -287,7 +286,7 @@ pub unsafe extern "C" fn verify_kzg_proof( )); *ok = result; - C_KZG_RET_OK + CKzgRet::Ok } /// # Safety @@ -298,11 +297,11 @@ pub unsafe extern "C" fn verify_blob_kzg_proof( commitment_bytes: *const Bytes48, proof_bytes: *const Bytes48, s: &CKZGSettings, -) -> C_KZG_RET { +) -> CKzgRet { let deserialized_blob = handle_ckzg_badargs!(deserialize_blob(blob)); let commitment_g1 = handle_ckzg_badargs!(FsG1::from_bytes(&(*commitment_bytes).bytes)); let proof_g1 = handle_ckzg_badargs!(FsG1::from_bytes(&(*proof_bytes).bytes)); - let settings = handle_ckzg_badargs!(kzg_settings_to_rust(s)); + let settings: FsKZGSettings = handle_ckzg_badargs!(s.try_into()); let result = handle_ckzg_badargs!(verify_blob_kzg_proof_rust( &deserialized_blob, @@ -312,7 +311,7 @@ pub unsafe extern "C" fn verify_blob_kzg_proof( )); *ok = result; - C_KZG_RET_OK + CKzgRet::Ok } /// # Safety @@ -324,31 +323,29 @@ pub unsafe extern "C" fn verify_blob_kzg_proof_batch( proofs_bytes: *const Bytes48, n: usize, s: &CKZGSettings, -) -> C_KZG_RET { +) -> CKzgRet { let raw_blobs = core::slice::from_raw_parts(blobs, n); let raw_commitments = core::slice::from_raw_parts(commitments_bytes, n); let raw_proofs = core::slice::from_raw_parts(proofs_bytes, n); - let deserialized_blobs: Result>, C_KZG_RET> = cfg_into_iter!(raw_blobs) - .map(|raw_blob| deserialize_blob(raw_blob).map_err(|_| C_KZG_RET_BADARGS)) + let deserialized_blobs: Result>, CKzgRet> = cfg_into_iter!(raw_blobs) + .map(|raw_blob| deserialize_blob(raw_blob).map_err(|_| CKzgRet::BadArgs)) .collect(); - let commitments_g1: Result, C_KZG_RET> = cfg_into_iter!(raw_commitments) - .map(|raw_commitment| { - FsG1::from_bytes(&raw_commitment.bytes).map_err(|_| C_KZG_RET_BADARGS) - }) + let commitments_g1: Result, CKzgRet> = cfg_into_iter!(raw_commitments) + .map(|raw_commitment| FsG1::from_bytes(&raw_commitment.bytes).map_err(|_| CKzgRet::BadArgs)) .collect(); - let proofs_g1: Result, C_KZG_RET> = cfg_into_iter!(raw_proofs) - .map(|raw_proof| FsG1::from_bytes(&raw_proof.bytes).map_err(|_| C_KZG_RET_BADARGS)) + let proofs_g1: Result, CKzgRet> = cfg_into_iter!(raw_proofs) + .map(|raw_proof| FsG1::from_bytes(&raw_proof.bytes).map_err(|_| CKzgRet::BadArgs)) .collect(); if let (Ok(blobs), Ok(commitments), Ok(proofs)) = (deserialized_blobs, commitments_g1, proofs_g1) { - let settings = match kzg_settings_to_rust(s) { + let settings: FsKZGSettings = match s.try_into() { Ok(value) => value, - Err(_) => return C_KZG_RET_BADARGS, + Err(_) => return CKzgRet::BadArgs, }; let result = @@ -356,13 +353,13 @@ pub unsafe extern "C" fn verify_blob_kzg_proof_batch( if let Ok(result) = result { *ok = result; - C_KZG_RET_OK + CKzgRet::Ok } else { - C_KZG_RET_BADARGS + CKzgRet::BadArgs } } else { *ok = false; - C_KZG_RET_BADARGS + CKzgRet::BadArgs } } @@ -374,7 +371,7 @@ pub unsafe extern "C" fn compute_kzg_proof( blob: *const Blob, z_bytes: *const Bytes32, s: &CKZGSettings, -) -> C_KZG_RET { +) -> CKzgRet { let deserialized_blob = match deserialize_blob(blob) { Ok(value) => value, Err(err) => return err, @@ -382,21 +379,21 @@ pub unsafe extern "C" fn compute_kzg_proof( let frz = match FsFr::from_bytes(&(*z_bytes).bytes) { Ok(value) => value, - Err(_) => return C_KZG_RET_BADARGS, + Err(_) => return CKzgRet::BadArgs, }; - let settings = match kzg_settings_to_rust(s) { + let settings: FsKZGSettings = match s.try_into() { Ok(value) => value, - Err(_) => return C_KZG_RET_BADARGS, + Err(_) => return CKzgRet::BadArgs, }; let (proof_out_tmp, fry_tmp) = match compute_kzg_proof_rust(&deserialized_blob, &frz, &settings) { Ok(value) => value, - Err(_) => return C_KZG_RET_BADARGS, + Err(_) => return CKzgRet::BadArgs, }; (*proof_out).bytes = proof_out_tmp.to_bytes(); (*y_out).bytes = fry_tmp.to_bytes(); - C_KZG_RET_OK + CKzgRet::Ok } diff --git a/mcl/src/eip_7594.rs b/mcl/src/eip_7594.rs index 3caabac64..2df8b46f6 100644 --- a/mcl/src/eip_7594.rs +++ b/mcl/src/eip_7594.rs @@ -1,284 +1,29 @@ extern crate alloc; -use alloc::string::{String, ToString}; -use alloc::vec; -use alloc::vec::Vec; - -use crate::{ - types::g1::FsG1, - utils::{deserialize_blob, kzg_settings_to_rust}, -}; -use kzg::{ - eip_4844::{ - Blob, Bytes48, CKZGSettings, Cell, KZGProof, BYTES_PER_FIELD_ELEMENT, CELLS_PER_EXT_BLOB, - C_KZG_RET, C_KZG_RET_BADARGS, C_KZG_RET_OK, FIELD_ELEMENTS_PER_CELL, - }, - Fr, G1, -}; - -use crate::types::{fr::FsFr, kzg_settings::FsKZGSettings}; - -pub fn compute_cells_and_kzg_proofs_rust( - cells: Option<&mut [[FsFr; FIELD_ELEMENTS_PER_CELL]]>, - proofs: Option<&mut [FsG1]>, - blob: &[FsFr], - s: &FsKZGSettings, -) -> Result<(), String> { - kzg::eip_7594::compute_cells_and_kzg_proofs(cells, proofs, blob, s) -} - -pub fn recover_cells_and_kzg_proofs_rust( - recovered_cells: &mut [[FsFr; FIELD_ELEMENTS_PER_CELL]], - recovered_proofs: Option<&mut [FsG1]>, - cell_indicies: &[usize], - cells: &[[FsFr; FIELD_ELEMENTS_PER_CELL]], - s: &FsKZGSettings, -) -> Result<(), String> { - kzg::eip_7594::recover_cells_and_kzg_proofs( - recovered_cells, - recovered_proofs, - cell_indicies, - cells, - s, - ) +use kzg::EcBackend; + +use crate::types::fft_settings::FsFFTSettings; +use crate::types::fp::FsFp; +use crate::types::g1::FsG1; +use crate::types::g1::FsG1Affine; +use crate::types::g2::FsG2; +use crate::types::kzg_settings::FsKZGSettings; +use crate::types::poly::FsPoly; +use kzg::c_bindings_eip7594; + +use crate::types::fr::FsFr; + +pub struct BlstBackend; + +impl EcBackend for BlstBackend { + type Fr = FsFr; + type G1Fp = FsFp; + type G1Affine = FsG1Affine; + type G1 = FsG1; + type G2 = FsG2; + type Poly = FsPoly; + type FFTSettings = FsFFTSettings; + type KZGSettings = FsKZGSettings; } -pub fn verify_cell_kzg_proof_batch_rust( - commitments: &[FsG1], - cell_indices: &[usize], - cells: &[[FsFr; FIELD_ELEMENTS_PER_CELL]], - proofs: &[FsG1], - s: &FsKZGSettings, -) -> Result { - kzg::eip_7594::verify_cell_kzg_proof_batch(commitments, cell_indices, cells, proofs, s) -} - -/// # Safety -#[no_mangle] -pub unsafe extern "C" fn compute_cells_and_kzg_proofs( - cells: *mut Cell, - proofs: *mut KZGProof, - blob: *const Blob, - settings: *const CKZGSettings, -) -> C_KZG_RET { - unsafe fn inner( - cells: *mut Cell, - proofs: *mut KZGProof, - blob: *const Blob, - settings: *const CKZGSettings, - ) -> Result<(), String> { - let mut cells_rs = if cells.is_null() { - None - } else { - Some(vec![ - [FsFr::default(); FIELD_ELEMENTS_PER_CELL]; - CELLS_PER_EXT_BLOB - ]) - }; - let mut proofs_rs = if proofs.is_null() { - None - } else { - Some(vec![FsG1::default(); CELLS_PER_EXT_BLOB]) - }; - - let blob = deserialize_blob(blob).map_err(|_| "Invalid blob".to_string())?; - let settings = kzg_settings_to_rust(&*settings)?; - - compute_cells_and_kzg_proofs_rust( - cells_rs.as_deref_mut(), - proofs_rs.as_deref_mut(), - &blob, - &settings, - )?; - - if let Some(cells_rs) = cells_rs { - let cells = core::slice::from_raw_parts_mut(cells, CELLS_PER_EXT_BLOB); - for (cell_index, cell) in cells_rs.iter().enumerate() { - for (fr_index, fr) in cell.iter().enumerate() { - cells[cell_index].bytes[(fr_index * BYTES_PER_FIELD_ELEMENT) - ..((fr_index + 1) * BYTES_PER_FIELD_ELEMENT)] - .copy_from_slice(&fr.to_bytes()); - } - } - } - - if let Some(proofs_rs) = proofs_rs { - let proofs = core::slice::from_raw_parts_mut(proofs, CELLS_PER_EXT_BLOB); - for (proof_index, proof) in proofs_rs.iter().enumerate() { - proofs[proof_index].bytes.copy_from_slice(&proof.to_bytes()); - } - } - - Ok(()) - } - - match inner(cells, proofs, blob, settings) { - Ok(()) => C_KZG_RET_OK, - Err(_) => C_KZG_RET_BADARGS, - } -} - -/// # Safety -#[no_mangle] -pub unsafe extern "C" fn recover_cells_and_kzg_proofs( - recovered_cells: *mut Cell, - recovered_proofs: *mut KZGProof, - cell_indices: *const u64, - cells: *const Cell, - num_cells: u64, - s: *const CKZGSettings, -) -> C_KZG_RET { - unsafe fn inner( - recovered_cells: *mut Cell, - recovered_proofs: *mut KZGProof, - cell_indices: *const u64, - cells: *const Cell, - num_cells: u64, - s: *const CKZGSettings, - ) -> Result<(), String> { - let mut recovered_cells_rs = - vec![[FsFr::default(); FIELD_ELEMENTS_PER_CELL]; CELLS_PER_EXT_BLOB]; - - let mut recovered_proofs_rs = if recovered_proofs.is_null() { - None - } else { - Some(vec![FsG1::default(); CELLS_PER_EXT_BLOB]) - }; - - let cell_indicies = core::slice::from_raw_parts(cell_indices, num_cells as usize) - .iter() - .map(|it| *it as usize) - .collect::>(); - let cells = core::slice::from_raw_parts(cells, num_cells as usize) - .iter() - .map(|it| -> Result<[FsFr; FIELD_ELEMENTS_PER_CELL], String> { - it.bytes - .chunks(BYTES_PER_FIELD_ELEMENT) - .map(FsFr::from_bytes) - .collect::, String>>() - .and_then(|frs| { - frs.try_into() - .map_err(|_| "Invalid field element count per cell".to_string()) - }) - }) - .collect::, String>>()?; - let settings = kzg_settings_to_rust(&*s)?; - - recover_cells_and_kzg_proofs_rust( - &mut recovered_cells_rs, - recovered_proofs_rs.as_deref_mut(), - &cell_indicies, - &cells, - &settings, - )?; - - let recovered_cells = core::slice::from_raw_parts_mut(recovered_cells, CELLS_PER_EXT_BLOB); - for (cell_c, cell_rs) in recovered_cells.iter_mut().zip(recovered_cells_rs.iter()) { - cell_c.bytes.copy_from_slice( - &cell_rs - .iter() - .flat_map(|fr| fr.to_bytes()) - .collect::>(), - ); - } - - if let Some(recovered_proofs_rs) = recovered_proofs_rs { - let recovered_proofs = - core::slice::from_raw_parts_mut(recovered_proofs, CELLS_PER_EXT_BLOB); - - for (proof_c, proof_rs) in recovered_proofs.iter_mut().zip(recovered_proofs_rs.iter()) { - proof_c.bytes = proof_rs.to_bytes(); - } - } - - Ok(()) - } - - match inner( - recovered_cells, - recovered_proofs, - cell_indices, - cells, - num_cells, - s, - ) { - Ok(()) => C_KZG_RET_OK, - Err(_) => C_KZG_RET_BADARGS, - } -} - -/// # Safety -#[no_mangle] -pub unsafe extern "C" fn verify_cell_kzg_proof_batch( - ok: *mut bool, - commitments_bytes: *const Bytes48, - cell_indices: *const u64, - cells: *const Cell, - proofs_bytes: *const Bytes48, - num_cells: u64, - s: *const CKZGSettings, -) -> C_KZG_RET { - unsafe fn inner( - ok: *mut bool, - commitments_bytes: *const Bytes48, - cell_indices: *const u64, - cells: *const Cell, - proofs_bytes: *const Bytes48, - num_cells: u64, - s: *const CKZGSettings, - ) -> Result<(), String> { - let commitments = core::slice::from_raw_parts(commitments_bytes, num_cells as usize) - .iter() - .map(|bytes| FsG1::from_bytes(&bytes.bytes)) - .collect::, String>>()?; - - let cell_indices = core::slice::from_raw_parts(cell_indices, num_cells as usize) - .iter() - .map(|it| *it as usize) - .collect::>(); - - let cells = core::slice::from_raw_parts(cells, num_cells as usize) - .iter() - .map(|it| -> Result<[FsFr; FIELD_ELEMENTS_PER_CELL], String> { - it.bytes - .chunks(BYTES_PER_FIELD_ELEMENT) - .map(FsFr::from_bytes) - .collect::, String>>() - .and_then(|frs| { - frs.try_into() - .map_err(|_| "Invalid field element count per cell".to_string()) - }) - }) - .collect::, String>>()?; - - let proofs = core::slice::from_raw_parts(proofs_bytes, num_cells as usize) - .iter() - .map(|bytes| FsG1::from_bytes(&bytes.bytes)) - .collect::, String>>()?; - - let settings = kzg_settings_to_rust(&*s)?; - - *ok = verify_cell_kzg_proof_batch_rust( - &commitments, - &cell_indices, - &cells, - &proofs, - &settings, - )?; - - Ok(()) - } - - match inner( - ok, - commitments_bytes, - cell_indices, - cells, - proofs_bytes, - num_cells, - s, - ) { - Ok(()) => C_KZG_RET_OK, - Err(_) => C_KZG_RET_BADARGS, - } -} +c_bindings_eip7594!(BlstBackend); diff --git a/mcl/src/kzg_proofs.rs b/mcl/src/kzg_proofs.rs index 0e56511cb..0bbddcee6 100644 --- a/mcl/src/kzg_proofs.rs +++ b/mcl/src/kzg_proofs.rs @@ -29,12 +29,46 @@ pub fn g1_linear_combination( len: usize, precomputation: Option<&PrecomputationTable>, ) { - *out = msm::( - points, - scalars, - len, - precomputation, - ); + #[cfg(feature = "sppark")] + { + use blst::{blst_fr, blst_scalar, blst_scalar_from_fr}; + use kzg::{G1Mul, G1}; + + if len < 8 { + *out = FsG1::default(); + for i in 0..len { + let tmp = points[i].mul(&scalars[i]); + out.add_or_dbl_assign(&tmp); + } + + return; + } + + let scalars = + unsafe { alloc::slice::from_raw_parts(scalars.as_ptr() as *const blst_fr, len) }; + + let point = if let Some(precomputation) = precomputation { + rust_kzg_mcl_sppark::multi_scalar_mult_prepared(precomputation.table, scalars) + } else { + let affines = kzg::msm::msm_impls::batch_convert::(&points); + let affines = unsafe { + alloc::slice::from_raw_parts(affines.as_ptr() as *const blst_p1_affine, len) + }; + rust_kzg_mcl_sppark::multi_scalar_mult(&affines[0..len], &scalars) + }; + + *out = FsG1(point); + } + + #[cfg(not(feature = "sppark"))] + { + *out = msm::( + points, + scalars, + len, + precomputation, + ); + } } pub fn pairings_verify(a1: &FsG1, a2: &FsG2, b1: &FsG1, b2: &FsG2) -> bool { diff --git a/mcl/src/types/kzg_settings.rs b/mcl/src/types/kzg_settings.rs index 7bed9bf9f..d74d14c4c 100644 --- a/mcl/src/types/kzg_settings.rs +++ b/mcl/src/types/kzg_settings.rs @@ -4,12 +4,10 @@ use alloc::string::{String, ToString}; use alloc::sync::Arc; use alloc::{vec, vec::Vec}; -use kzg::eip_4844::{ - FIELD_ELEMENTS_PER_BLOB, FIELD_ELEMENTS_PER_CELL, FIELD_ELEMENTS_PER_EXT_BLOB, - TRUSTED_SETUP_NUM_G2_POINTS, -}; +use kzg::eth::c_bindings::CKZGSettings; +use kzg::eth::{self, FIELD_ELEMENTS_PER_EXT_BLOB}; use kzg::msm::precompute::{precompute, PrecomputationTable}; -use kzg::{FFTFr, FFTSettings, Fr, G1Mul, G2Mul, KZGSettings, Poly, G1, G2}; +use kzg::{FFTFr, FFTSettings, Fr, G1Mul, G2Mul, KZGSettings, Poly, Preset, G1, G2}; use crate::consts::{G1_GENERATOR, G2_GENERATOR}; use crate::fft_g1::fft_g1_fast; @@ -19,6 +17,7 @@ use crate::types::fr::FsFr; use crate::types::g1::FsG1; use crate::types::g2::FsG2; use crate::types::poly::FsPoly; +use crate::utils::PRECOMPUTATION_TABLES; use super::fp::FsFp; use super::g1::FsG1Affine; @@ -33,28 +32,30 @@ pub struct FsKZGSettings { pub x_ext_fft_columns: Vec>, } -fn g1_fft(output: &mut [FsG1], input: &[FsG1], s: &FsFFTSettings) -> Result<(), String> { - // g1_t *out, const g1_t *in, size_t n, const KZGSettings *s - +fn g1_fft(output: &mut [FsG1], input: &[FsG1], s: &FsFFTSettings) -> Result<(), String> { /* Ensure the length is valid */ - if input.len() > FIELD_ELEMENTS_PER_EXT_BLOB || !input.len().is_power_of_two() { + if input.len() > P::FIELD_ELEMENTS_PER_EXT_BLOB || !input.len().is_power_of_two() { return Err("Invalid input size".to_string()); } - let roots_stride = FIELD_ELEMENTS_PER_EXT_BLOB / input.len(); + let roots_stride = P::FIELD_ELEMENTS_PER_EXT_BLOB / input.len(); fft_g1_fast(output, input, 1, &s.roots_of_unity, roots_stride); Ok(()) } -fn toeplitz_part_1(output: &mut [FsG1], x: &[FsG1], s: &FsFFTSettings) -> Result<(), String> { +fn toeplitz_part_1( + output: &mut [FsG1], + x: &[FsG1], + s: &FsFFTSettings, +) -> Result<(), String> { let n = x.len(); let n2 = n * 2; let mut x_ext = vec![FsG1::identity(); n2]; x_ext[..n].copy_from_slice(x); - g1_fft(output, &x_ext, s)?; + g1_fft::

(output, &x_ext, s)?; Ok(()) } @@ -66,14 +67,27 @@ impl KZGSettings for g2_monomial: &[FsG2], fft_settings: &FsFFTSettings, ) -> Result { - if g1_monomial.len() != FIELD_ELEMENTS_PER_BLOB - || g1_lagrange_brp.len() != FIELD_ELEMENTS_PER_BLOB - || g2_monomial.len() != TRUSTED_SETUP_NUM_G2_POINTS + Self::new_for_preset::<{ eth::FIELD_ELEMENTS_PER_CELL }, eth::Mainnet>( + g1_monomial, + g1_lagrange_brp, + g2_monomial, + fft_settings, + ) + } + + fn new_for_preset( + g1_monomial: &[FsG1], + g1_lagrange_brp: &[FsG1], + g2_monomial: &[FsG2], + fft_settings: &FsFFTSettings, + ) -> Result { + if g1_monomial.len() != P::FIELD_ELEMENTS_PER_BLOB + || g1_lagrange_brp.len() != P::FIELD_ELEMENTS_PER_BLOB { return Err("Length does not match FIELD_ELEMENTS_PER_BLOB".to_string()); } - let n = FIELD_ELEMENTS_PER_EXT_BLOB / 2; + let n = P::FIELD_ELEMENTS_PER_EXT_BLOB / 2; let k = n / FIELD_ELEMENTS_PER_CELL; let k2 = 2 * k; @@ -89,32 +103,13 @@ impl KZGSettings for } x[k - 1] = FsG1::identity(); - toeplitz_part_1(&mut points, &x, fft_settings)?; + toeplitz_part_1::

(&mut points, &x, fft_settings)?; for row in 0..k2 { x_ext_fft_columns[row][offset] = points[row]; } } - // for (size_t offset = 0; offset < FIELD_ELEMENTS_PER_CELL; offset++) { - // /* Compute x, sections of the g1 values */ - // size_t start = n - FIELD_ELEMENTS_PER_CELL - 1 - offset; - // for (size_t i = 0; i < k - 1; i++) { - // size_t j = start - i * FIELD_ELEMENTS_PER_CELL; - // x[i] = s->g1_values_monomial[j]; - // } - // x[k - 1] = G1_IDENTITY; - - // /* Compute points, the fft of an extended x */ - // ret = toeplitz_part_1(points, x, k, s); - // if (ret != C_KZG_OK) goto out; - - // /* Reorganize from rows into columns */ - // for (size_t row = 0; row < k2; row++) { - // s->x_ext_fft_columns[row][offset] = points[row]; - // } - // } - Ok(Self { g1_values_monomial: g1_monomial.to_vec(), g1_values_lagrange_brp: g1_lagrange_brp.to_vec(), @@ -122,7 +117,25 @@ impl KZGSettings for fs: fft_settings.clone(), x_ext_fft_columns, precomputation: { - precompute(g1_lagrange_brp).ok().flatten().map(Arc::new) + #[cfg(feature = "sppark")] + { + use blst::blst_p1_affine; + let points = + kzg::msm::msm_impls::batch_convert::(secret_g1); + let points = unsafe { + alloc::slice::from_raw_parts( + points.as_ptr() as *const blst_p1_affine, + points.len(), + ) + }; + let prepared = rust_kzg_mcl_sppark::prepare_multi_scalar_mult(points); + Some(Arc::new(PrecomputationTable::from_ptr(prepared))) + } + + #[cfg(not(feature = "sppark"))] + { + precompute(g1_lagrange_brp).ok().flatten().map(Arc::new) + } }, }) } @@ -296,3 +309,87 @@ impl KZGSettings for &self.x_ext_fft_columns[index] } } + +impl<'a> TryFrom<&'a CKZGSettings> for FsKZGSettings { + type Error = String; + + fn try_from(settings: &'a CKZGSettings) -> Result { + let roots_of_unity = unsafe { + core::slice::from_raw_parts(settings.roots_of_unity, FIELD_ELEMENTS_PER_EXT_BLOB + 1) + .iter() + .map(|r| FsFr(*r)) + .collect::>() + }; + + let brp_roots_of_unity = unsafe { + core::slice::from_raw_parts(settings.brp_roots_of_unity, FIELD_ELEMENTS_PER_EXT_BLOB) + .iter() + .map(|r| FsFr(*r)) + .collect::>() + }; + + let reverse_roots_of_unity = unsafe { + core::slice::from_raw_parts( + settings.reverse_roots_of_unity, + FIELD_ELEMENTS_PER_EXT_BLOB + 1, + ) + .iter() + .map(|r| FsFr(*r)) + .collect::>() + }; + + let fft_settings = FsFFTSettings { + max_width: FIELD_ELEMENTS_PER_EXT_BLOB, + root_of_unity: roots_of_unity[1], + roots_of_unity, + brp_roots_of_unity, + reverse_roots_of_unity, + }; + + Ok(FsKZGSettings { + fs: fft_settings, + g1_values_monomial: unsafe { + core::slice::from_raw_parts( + settings.g1_values_monomial, + eth::FIELD_ELEMENTS_PER_BLOB, + ) + } + .iter() + .map(|r| FsG1(*r)) + .collect::>(), + g1_values_lagrange_brp: unsafe { + core::slice::from_raw_parts( + settings.g1_values_lagrange_brp, + eth::FIELD_ELEMENTS_PER_BLOB, + ) + } + .iter() + .map(|r| FsG1(*r)) + .collect::>(), + g2_values_monomial: unsafe { + core::slice::from_raw_parts( + settings.g2_values_monomial, + eth::TRUSTED_SETUP_NUM_G2_POINTS, + ) + } + .iter() + .map(|r| FsG2(*r)) + .collect::>(), + x_ext_fft_columns: unsafe { + core::slice::from_raw_parts( + settings.x_ext_fft_columns, + 2 * ((FIELD_ELEMENTS_PER_EXT_BLOB / 2) / eth::FIELD_ELEMENTS_PER_CELL), + ) + } + .iter() + .map(|it| { + unsafe { core::slice::from_raw_parts(*it, eth::FIELD_ELEMENTS_PER_CELL) } + .iter() + .map(|it| FsG1(*it)) + .collect::>() + }) + .collect::>(), + precomputation: unsafe { PRECOMPUTATION_TABLES.get_precomputation(settings) }, + }) + } +} diff --git a/mcl/src/utils.rs b/mcl/src/utils.rs index b1263c55b..1605c6c2b 100644 --- a/mcl/src/utils.rs +++ b/mcl/src/utils.rs @@ -1,18 +1,13 @@ extern crate alloc; use alloc::boxed::Box; -use alloc::string::String; use alloc::vec::Vec; -use kzg::eip_4844::{ - hash_to_bls_field, Blob, CKZGSettings, PrecomputationTableManager, BYTES_PER_FIELD_ELEMENT, - C_KZG_RET, C_KZG_RET_BADARGS, FIELD_ELEMENTS_PER_BLOB, FIELD_ELEMENTS_PER_CELL, - FIELD_ELEMENTS_PER_EXT_BLOB, TRUSTED_SETUP_NUM_G2_POINTS, -}; +use kzg::eip_4844::{hash_to_bls_field, PrecomputationTableManager, BYTES_PER_FIELD_ELEMENT}; +use kzg::eth::c_bindings::{Blob, CKZGSettings, CKzgRet}; use kzg::{Fr, G1Mul, G2Mul}; use crate::consts::{G1_GENERATOR, G2_GENERATOR}; -use crate::types::fft_settings::FsFFTSettings; use crate::types::fp::FsFp; use crate::types::fr::FsFr; use crate::types::g1::{FsG1, FsG1Affine}; @@ -32,7 +27,7 @@ pub fn generate_trusted_setup( for _ in 0..n { s1.push(G1_GENERATOR.mul(&s_pow)); - s2.push(G1_GENERATOR); // TODO: this should be lagrange form + s2.push(G1_GENERATOR.mul(&s_pow)); // TODO: this should be lagrange form s3.push(G2_GENERATOR.mul(&s_pow)); s_pow = s_pow.mul(&s); @@ -41,7 +36,7 @@ pub fn generate_trusted_setup( (s1, s2, s3) } -pub(crate) unsafe fn deserialize_blob(blob: *const Blob) -> Result, C_KZG_RET> { +pub(crate) unsafe fn deserialize_blob(blob: *const Blob) -> Result, CKzgRet> { (*blob) .bytes .chunks(BYTES_PER_FIELD_ELEMENT) @@ -51,61 +46,23 @@ pub(crate) unsafe fn deserialize_blob(blob: *const Blob) -> Result, C_ if let Ok(result) = FsFr::from_bytes(&bytes) { Ok(result) } else { - Err(C_KZG_RET_BADARGS) + Err(CKzgRet::BadArgs) } }) - .collect::, C_KZG_RET>>() + .collect::, CKzgRet>>() } macro_rules! handle_ckzg_badargs { ($x: expr) => { match $x { Ok(value) => value, - Err(_) => return kzg::eip_4844::C_KZG_RET_BADARGS, + Err(_) => return kzg::eth::c_bindings::CKzgRet::BadArgs, } }; } pub(crate) use handle_ckzg_badargs; -pub(crate) fn fft_settings_to_rust( - c_settings: *const CKZGSettings, -) -> Result { - let settings = unsafe { &*c_settings }; - - let roots_of_unity = unsafe { - core::slice::from_raw_parts(settings.roots_of_unity, FIELD_ELEMENTS_PER_EXT_BLOB + 1) - .iter() - .map(|r| FsFr(*r)) - .collect::>() - }; - - let brp_roots_of_unity = unsafe { - core::slice::from_raw_parts(settings.brp_roots_of_unity, FIELD_ELEMENTS_PER_EXT_BLOB) - .iter() - .map(|r| FsFr(*r)) - .collect::>() - }; - - let reverse_roots_of_unity = unsafe { - core::slice::from_raw_parts( - settings.reverse_roots_of_unity, - FIELD_ELEMENTS_PER_EXT_BLOB + 1, - ) - .iter() - .map(|r| FsFr(*r)) - .collect::>() - }; - - Ok(FsFFTSettings { - max_width: FIELD_ELEMENTS_PER_EXT_BLOB, - root_of_unity: roots_of_unity[1], - roots_of_unity, - brp_roots_of_unity, - reverse_roots_of_unity, - }) -} - pub(crate) static mut PRECOMPUTATION_TABLES: PrecomputationTableManager< FsFr, FsG1, @@ -113,45 +70,6 @@ pub(crate) static mut PRECOMPUTATION_TABLES: PrecomputationTableManager< FsG1Affine, > = PrecomputationTableManager::new(); -pub(crate) fn kzg_settings_to_rust(c_settings: &CKZGSettings) -> Result { - Ok(FsKZGSettings { - fs: fft_settings_to_rust(c_settings)?, - g1_values_monomial: unsafe { - core::slice::from_raw_parts(c_settings.g1_values_monomial, FIELD_ELEMENTS_PER_BLOB) - } - .iter() - .map(|r| FsG1(*r)) - .collect::>(), - g1_values_lagrange_brp: unsafe { - core::slice::from_raw_parts(c_settings.g1_values_lagrange_brp, FIELD_ELEMENTS_PER_BLOB) - } - .iter() - .map(|r| FsG1(*r)) - .collect::>(), - g2_values_monomial: unsafe { - core::slice::from_raw_parts(c_settings.g2_values_monomial, TRUSTED_SETUP_NUM_G2_POINTS) - } - .iter() - .map(|r| FsG2(*r)) - .collect::>(), - x_ext_fft_columns: unsafe { - core::slice::from_raw_parts( - c_settings.x_ext_fft_columns, - 2 * ((FIELD_ELEMENTS_PER_EXT_BLOB / 2) / FIELD_ELEMENTS_PER_CELL), - ) - } - .iter() - .map(|it| { - unsafe { core::slice::from_raw_parts(*it, FIELD_ELEMENTS_PER_CELL) } - .iter() - .map(|it| FsG1(*it)) - .collect::>() - }) - .collect::>(), - precomputation: unsafe { PRECOMPUTATION_TABLES.get_precomputation(c_settings) }, - }) -} - pub(crate) fn kzg_settings_to_c(rust_settings: &FsKZGSettings) -> CKZGSettings { CKZGSettings { roots_of_unity: Box::leak( diff --git a/mcl/tests/eip_7594.rs b/mcl/tests/eip_7594.rs index 9af9ae96e..1d85a2861 100644 --- a/mcl/tests/eip_7594.rs +++ b/mcl/tests/eip_7594.rs @@ -1,7 +1,8 @@ #[cfg(test)] mod tests { - use kzg::eip_4844::{ - blob_to_kzg_commitment_rust, bytes_to_blob, CELLS_PER_EXT_BLOB, FIELD_ELEMENTS_PER_CELL, + use kzg::{ + eip_4844::{blob_to_kzg_commitment_rust, bytes_to_blob}, + eth, DAS, }; use kzg_bench::tests::{ eip_4844::generate_random_blob_bytes, @@ -13,53 +14,26 @@ mod tests { }; use rust_kzg_mcl::{ eip_4844::load_trusted_setup_filename_rust, - eip_7594::{ - compute_cells_and_kzg_proofs_rust, recover_cells_and_kzg_proofs_rust, - verify_cell_kzg_proof_batch_rust, - }, - types::{ - fft_settings::FsFFTSettings, - fp::FsFp, - fr::FsFr, - g1::{FsG1, FsG1Affine}, - g2::FsG2, - kzg_settings::FsKZGSettings, - poly::FsPoly, - }, + eip_7594::BlstBackend, + types::{fr::FsFr, g1::FsG1, kzg_settings::FsKZGSettings}, }; #[test] pub fn test_vectors_compute_cells_and_kzg_proofs_() { - test_vectors_compute_cells_and_kzg_proofs::< - FsFr, - FsG1, - FsG2, - FsPoly, - FsFFTSettings, - FsKZGSettings, - FsFp, - FsG1Affine, - >( + test_vectors_compute_cells_and_kzg_proofs::( &load_trusted_setup_filename_rust, - &compute_cells_and_kzg_proofs_rust, &bytes_to_blob, ); } #[test] pub fn test_vectors_recover_cells_and_kzg_proofs_() { - test_vectors_recover_cells_and_kzg_proofs( - &load_trusted_setup_filename_rust, - &recover_cells_and_kzg_proofs_rust, - ); + test_vectors_recover_cells_and_kzg_proofs::(&load_trusted_setup_filename_rust); } #[test] pub fn test_vectors_verify_cell_kzg_proof_batch_() { - test_vectors_verify_cell_kzg_proof_batch( - &load_trusted_setup_filename_rust, - &verify_cell_kzg_proof_batch_rust, - ); + test_vectors_verify_cell_kzg_proof_batch::(&load_trusted_setup_filename_rust); } #[test] @@ -69,50 +43,46 @@ mod tests { /* Get a random blob */ let blob_bytes = generate_random_blob_bytes(&mut rng); - let blob = bytes_to_blob(&blob_bytes).unwrap(); + let blob: Vec = bytes_to_blob(&blob_bytes).unwrap(); - let mut cells = - vec![ - core::array::from_fn::<_, FIELD_ELEMENTS_PER_CELL, _>(|_| FsFr::default()); - CELLS_PER_EXT_BLOB - ]; - let mut proofs = vec![FsG1::default(); CELLS_PER_EXT_BLOB]; + let mut cells: Vec<[FsFr; eth::FIELD_ELEMENTS_PER_CELL]> = + vec![core::array::from_fn(|_| FsFr::default()); eth::CELLS_PER_EXT_BLOB]; + let mut proofs = vec![FsG1::default(); eth::CELLS_PER_EXT_BLOB]; /* Get the cells and proofs */ - let mut result = compute_cells_and_kzg_proofs_rust( - Some(&mut cells), - Some(&mut proofs), - &blob, - &settings, + let mut result = >::compute_cells_and_kzg_proofs( + &settings, Some(&mut cells), Some(&mut proofs), &blob ); assert!(result.is_ok()); - let cell_indices: Vec = (0..).step_by(2).take(CELLS_PER_EXT_BLOB / 2).collect(); - let mut partial_cells = - vec![ - core::array::from_fn::<_, FIELD_ELEMENTS_PER_CELL, _>(|_| FsFr::default()); - CELLS_PER_EXT_BLOB / 2 - ]; + let cell_indices: Vec = (0..).step_by(2).take(eth::CELLS_PER_EXT_BLOB / 2).collect(); + let mut partial_cells: Vec<[FsFr; eth::FIELD_ELEMENTS_PER_CELL]> = + vec![core::array::from_fn(|_| FsFr::default()); eth::CELLS_PER_EXT_BLOB / 2]; /* Erase half of the cells */ - for i in 0..(CELLS_PER_EXT_BLOB / 2) { + for i in 0..(eth::CELLS_PER_EXT_BLOB / 2) { partial_cells[i] = cells[cell_indices[i]]; } - let mut recovered_cells = - vec![ - core::array::from_fn::<_, FIELD_ELEMENTS_PER_CELL, _>(|_| FsFr::default()); - CELLS_PER_EXT_BLOB - ]; - let mut recovered_proofs = vec![FsG1::default(); CELLS_PER_EXT_BLOB]; + let mut recovered_cells: Vec<[FsFr; eth::FIELD_ELEMENTS_PER_CELL]> = + vec![core::array::from_fn(|_| FsFr::default()); eth::CELLS_PER_EXT_BLOB]; + let mut recovered_proofs = vec![FsG1::default(); eth::CELLS_PER_EXT_BLOB]; /* Reconstruct with half of the cells */ - result = recover_cells_and_kzg_proofs_rust( + result = >::recover_cells_and_kzg_proofs( + &settings, &mut recovered_cells, Some(&mut recovered_proofs), &cell_indices, &partial_cells, - &settings, ); assert!(result.is_ok()); @@ -135,34 +105,32 @@ mod tests { assert!(commitment_result.is_ok()); let commitment = commitment_result.unwrap(); - let mut cells = - vec![ - core::array::from_fn::<_, FIELD_ELEMENTS_PER_CELL, _>(|_| FsFr::default()); - CELLS_PER_EXT_BLOB - ]; - let mut proofs = vec![FsG1::default(); CELLS_PER_EXT_BLOB]; + let mut cells: Vec<[FsFr; eth::FIELD_ELEMENTS_PER_CELL]> = + vec![core::array::from_fn(|_| FsFr::default()); eth::CELLS_PER_EXT_BLOB]; + let mut proofs = vec![FsG1::default(); eth::CELLS_PER_EXT_BLOB]; /* Compute cells and proofs */ - let result = compute_cells_and_kzg_proofs_rust( - Some(&mut cells), - Some(&mut proofs), - &blob, - &settings, + let result = >::compute_cells_and_kzg_proofs( + &settings, Some(&mut cells), Some(&mut proofs), &blob ); assert!(result.is_ok()); /* Initialize list of commitments & cell indices */ - let commitments = vec![commitment; CELLS_PER_EXT_BLOB]; + let commitments = vec![commitment; eth::CELLS_PER_EXT_BLOB]; - let cell_indices: Vec = (0..).step_by(1).take(CELLS_PER_EXT_BLOB).collect(); + let cell_indices: Vec = (0..).step_by(1).take(eth::CELLS_PER_EXT_BLOB).collect(); /* Verify all the proofs */ - let verify_result = verify_cell_kzg_proof_batch_rust( - &commitments, - &cell_indices, - &cells, - &proofs, - &settings, + let verify_result = >::verify_cell_kzg_proof_batch( + &settings, &commitments, &cell_indices, &cells, &proofs ); assert!(verify_result.is_ok()); } diff --git a/mcl/tests/fk20_proofs.rs b/mcl/tests/fk20_proofs.rs index ac57c34a4..c57f9e5c4 100644 --- a/mcl/tests/fk20_proofs.rs +++ b/mcl/tests/fk20_proofs.rs @@ -1,110 +1,38 @@ #[cfg(test)] mod tests { use kzg_bench::tests::fk20_proofs::*; - use rust_kzg_mcl::types::fft_settings::FsFFTSettings; + use rust_kzg_mcl::eip_7594::BlstBackend; use rust_kzg_mcl::types::fk20_multi_settings::FsFK20MultiSettings; use rust_kzg_mcl::types::fk20_single_settings::FsFK20SingleSettings; - use rust_kzg_mcl::types::fp::FsFp; - use rust_kzg_mcl::types::fr::FsFr; - use rust_kzg_mcl::types::g1::{FsG1, FsG1Affine}; - use rust_kzg_mcl::types::g2::FsG2; - use rust_kzg_mcl::types::kzg_settings::FsKZGSettings; - use rust_kzg_mcl::types::poly::FsPoly; use rust_kzg_mcl::utils::generate_trusted_setup; - #[ignore = "KZG settings loading doesn't support trusted setup sizes other than FIELD_ELEMENTS_PER_BLOB (4096 points)"] #[test] fn test_fk_single() { - fk_single::< - FsFr, - FsG1, - FsG2, - FsPoly, - FsFFTSettings, - FsKZGSettings, - FsFK20SingleSettings, - FsFp, - FsG1Affine, - >(&generate_trusted_setup); + fk_single::(&generate_trusted_setup); } - #[ignore = "KZG settings loading doesn't support trusted setup sizes other than FIELD_ELEMENTS_PER_BLOB (4096 points)"] #[test] fn test_fk_single_strided() { - fk_single_strided::< - FsFr, - FsG1, - FsG2, - FsPoly, - FsFFTSettings, - FsKZGSettings, - FsFK20SingleSettings, - FsFp, - FsG1Affine, - >(&generate_trusted_setup); + fk_single_strided::(&generate_trusted_setup); } - #[ignore = "KZG settings loading doesn't support trusted setup sizes other than FIELD_ELEMENTS_PER_BLOB (4096 points)"] #[test] fn test_fk_multi_settings() { - fk_multi_settings::< - FsFr, - FsG1, - FsG2, - FsPoly, - FsFFTSettings, - FsKZGSettings, - FsFK20MultiSettings, - FsFp, - FsG1Affine, - >(&generate_trusted_setup); + fk_multi_settings::(&generate_trusted_setup); } - #[ignore = "KZG settings loading doesn't support trusted setup sizes other than FIELD_ELEMENTS_PER_BLOB (4096 points)"] #[test] fn test_fk_multi_chunk_len_1_512() { - fk_multi_chunk_len_1_512::< - FsFr, - FsG1, - FsG2, - FsPoly, - FsFFTSettings, - FsKZGSettings, - FsFK20MultiSettings, - FsFp, - FsG1Affine, - >(&generate_trusted_setup); + fk_multi_chunk_len_1_512::(&generate_trusted_setup); } - #[ignore = "KZG settings loading doesn't support trusted setup sizes other than FIELD_ELEMENTS_PER_BLOB (4096 points)"] #[test] fn test_fk_multi_chunk_len_16_512() { - fk_multi_chunk_len_16_512::< - FsFr, - FsG1, - FsG2, - FsPoly, - FsFFTSettings, - FsKZGSettings, - FsFK20MultiSettings, - FsFp, - FsG1Affine, - >(&generate_trusted_setup); + fk_multi_chunk_len_16_512::(&generate_trusted_setup); } - #[ignore = "KZG settings loading doesn't support trusted setup sizes other than FIELD_ELEMENTS_PER_BLOB (4096 points)"] #[test] fn test_fk_multi_chunk_len_16_16() { - fk_multi_chunk_len_16_16::< - FsFr, - FsG1, - FsG2, - FsPoly, - FsFFTSettings, - FsKZGSettings, - FsFK20MultiSettings, - FsFp, - FsG1Affine, - >(&generate_trusted_setup); + fk_multi_chunk_len_16_16::(&generate_trusted_setup); } } diff --git a/mcl/tests/kzg_proofs.rs b/mcl/tests/kzg_proofs.rs index 2605dbddf..ef9ceba9e 100644 --- a/mcl/tests/kzg_proofs.rs +++ b/mcl/tests/kzg_proofs.rs @@ -1,61 +1,89 @@ #[cfg(test)] mod tests { + use blst::{ + blst_final_exp, blst_fp12, blst_fp12_mul, blst_miller_loop, blst_p1_affine, blst_p1_cneg, + blst_p1_to_affine, blst_p2_affine, blst_p2_to_affine, Pairing, + }; + use kzg::G1; use kzg_bench::tests::kzg_proofs::{ commit_to_nil_poly, commit_to_too_long_poly_returns_err, proof_multi, proof_single, }; - use rust_kzg_mcl::types::fft_settings::FsFFTSettings; - use rust_kzg_mcl::types::fp::FsFp; - use rust_kzg_mcl::types::fr::FsFr; - use rust_kzg_mcl::types::g1::{FsG1, FsG1Affine}; + use rust_kzg_mcl::eip_7594::BlstBackend; + use rust_kzg_mcl::types::g1::FsG1; use rust_kzg_mcl::types::g2::FsG2; - use rust_kzg_mcl::types::kzg_settings::FsKZGSettings; - use rust_kzg_mcl::types::poly::FsPoly; use rust_kzg_mcl::utils::generate_trusted_setup; - #[ignore = "KZG settings loading doesn't support trusted setup sizes other than FIELD_ELEMENTS_PER_BLOB (4096 points)"] #[test] pub fn test_proof_single() { - proof_single::( - &generate_trusted_setup, - ); + proof_single::(&generate_trusted_setup); } - #[ignore = "KZG settings loading doesn't support trusted setup sizes other than FIELD_ELEMENTS_PER_BLOB (4096 points)"] #[test] pub fn test_commit_to_nil_poly() { - commit_to_nil_poly::< - FsFr, - FsG1, - FsG2, - FsPoly, - FsFFTSettings, - FsKZGSettings, - FsFp, - FsG1Affine, - >(&generate_trusted_setup); + commit_to_nil_poly::(&generate_trusted_setup); } - #[ignore = "KZG settings loading doesn't support trusted setup sizes other than FIELD_ELEMENTS_PER_BLOB (4096 points)"] #[test] pub fn test_commit_to_too_long_poly() { - commit_to_too_long_poly_returns_err::< - FsFr, - FsG1, - FsG2, - FsPoly, - FsFFTSettings, - FsKZGSettings, - FsFp, - FsG1Affine, - >(&generate_trusted_setup); + commit_to_too_long_poly_returns_err::(&generate_trusted_setup); } - #[ignore = "KZG settings loading doesn't support trusted setup sizes other than FIELD_ELEMENTS_PER_BLOB (4096 points)"] #[test] pub fn test_proof_multi() { - proof_multi::( - &generate_trusted_setup, - ); + proof_multi::(&generate_trusted_setup); + } + + // This aims at showing that the use of the blst::Pairing engine in pairings_verify + // has the desired semantics. + #[cfg(feature = "rand")] + fn og_pairings_verify() { + let a1 = FsG1::rand(); + let a2 = FsG2::rand(); + let b1 = FsG1::rand(); + let b2 = FsG2::rand(); + + let mut loop0 = blst_fp12::default(); + let mut loop1 = blst_fp12::default(); + let mut gt_point = blst_fp12::default(); + + let mut aa1 = blst_p1_affine::default(); + let mut bb1 = blst_p1_affine::default(); + + let mut aa2 = blst_p2_affine::default(); + let mut bb2 = blst_p2_affine::default(); + + // As an optimisation, we want to invert one of the pairings, + // so we negate one of the points. + let mut a1neg: FsG1 = a1; + unsafe { + blst_p1_cneg(&mut a1neg.0, true); + blst_p1_to_affine(&mut aa1, &a1neg.0); + + blst_p1_to_affine(&mut bb1, &b1.0); + blst_p2_to_affine(&mut aa2, &a2.0); + blst_p2_to_affine(&mut bb2, &b2.0); + + blst_miller_loop(&mut loop0, &aa2, &aa1); + blst_miller_loop(&mut loop1, &bb2, &bb1); + + blst_fp12_mul(&mut gt_point, &loop0, &loop1); + blst_final_exp(&mut gt_point, >_point); + + let dst = [0u8; 3]; + let mut pairing_blst = Pairing::new(false, &dst); + pairing_blst.raw_aggregate(&aa2, &aa1); + pairing_blst.raw_aggregate(&bb2, &bb1); + + assert_eq!(gt_point, pairing_blst.as_fp12().final_exp()); + } + } + + #[cfg(feature = "rand")] + #[test] + pub fn test_pairings_verify() { + for _i in 0..100 { + og_pairings_verify(); + } } }