Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EIP-7594 - Seeking feeback on computing roots of unity and finite fields implementations #262

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
283 changes: 257 additions & 26 deletions Cargo.lock

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion arkworks/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ ark-serialize = { version = "^0.4.2", default-features = false }
hex = "0.4.3"
rand = { version = "0.8.5", optional = true }
libc = { version = "0.2.148", default-features = false }
rayon = { version = "1.8.0", optional = true }
rayon = { version = "1.9.0", optional = true }

[dev-dependencies]
criterion = "0.5.1"
Expand Down Expand Up @@ -47,6 +47,9 @@ bgmw = [
arkmsm = [
"kzg/arkmsm"
]
cuda = [
"kzg/cuda"
]

[[bench]]
name = "fft"
Expand Down
3 changes: 2 additions & 1 deletion arkworks/benches/eip_4844.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ 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_kzg_proof_rust, verify_blob_kzg_proof_batch_rust, verify_blob_kzg_proof_rust,
verify_kzg_proof_rust,
verify_kzg_proof_rust, compute_cells_and_kzg_proofs_rust,
};
use kzg_bench::benches::eip_4844::bench_eip_4844;
use rust_kzg_arkworks::eip_4844::load_trusted_setup_filename_rust;
Expand All @@ -21,6 +21,7 @@ fn bench_eip_4844_(c: &mut Criterion) {
&compute_blob_kzg_proof_rust,
&verify_blob_kzg_proof_rust,
&verify_blob_kzg_proof_batch_rust,
&compute_cells_and_kzg_proofs_rust
);
}

Expand Down
17 changes: 16 additions & 1 deletion arkworks/src/eip_4844.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use kzg::eip_4844::{
verify_kzg_proof_rust, 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,
TRUSTED_SETUP_NUM_G2_POINTS, BYTES_PER_BLOB,
};
use kzg::{cfg_into_iter, Fr, G1};
use std::ptr::null_mut;
Expand Down Expand Up @@ -423,3 +423,18 @@ pub unsafe extern "C" fn compute_kzg_proof(
(*y_out).bytes = fry_tmp.to_bytes();
C_KZG_RET_OK
}


/// # Safety
#[no_mangle]
pub unsafe extern "C" fn compute_cells_and_kzg_proofs(
cells: *mut Cell,
proofs: *mut KZGProof,
blob: *const Blob,
s: &CKZGSettings,
) -> CKZGSettings {
// Check for null pointers
if cells.is_null() || proofs.is_null() || blob.is_null() || s.is_null() {
return C_KZG_RET_BADARGS;
}
}
11 changes: 11 additions & 0 deletions arkworks/src/kzg_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use crate::utils::{
use ark_bls12_381::{g1, g2, Fr, G1Affine, G2Affine};
use ark_ec::{models::short_weierstrass::Projective, AffineRepr, Group};
use ark_ec::{CurveConfig, CurveGroup};
use ark_ff::BigInt;
use ark_ff::{biginteger::BigInteger256, BigInteger, Field};
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
use ark_std::{One, Zero};
Expand Down Expand Up @@ -840,6 +841,16 @@ impl G1Fp for ArkFp {
Self(default)
}

fn to_limbs(&self) -> [u64; 6] {
self.0.0.0
}

fn from_bytes_le(bytes: &[u8; 48]) -> Self {
let storage: [u64; 6] = bytes.chunks(8).map(|it| u64::from_le_bytes(it.try_into().unwrap())).collect::<Vec<_>>().try_into().unwrap();
let big_int = BigInt::new(storage);
Self(ArkFpInt::from(big_int))
}

fn neg_assign(&mut self) {
self.0 = -self.0;
}
Expand Down
12 changes: 12 additions & 0 deletions blst/src/types/fp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,18 @@ impl G1Fp for FsFp {
],
});

fn to_limbs(&self) -> [u64; 6] {
self.0.l
}

fn from_bytes_le(bytes: &[u8; 48]) -> Self {
let mut limbs = [0u64; 6];
for i in 0..6 {
limbs[i] = u64::from_le_bytes(bytes[i*8..(i+1)*8].try_into().unwrap());
}
Self(blst_fp { l: limbs})
}

fn inverse(&self) -> Option<Self> {
let mut out: Self = *self;
unsafe {
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,6 @@
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_kzg_proof_rust, verify_blob_kzg_proof_batch_rust, verify_blob_kzg_proof_rust,
verify_kzg_proof_rust,
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
};
use kzg_bench::benches::eip_4844::bench_eip_4844;
use rust_kzg_constantine::{
Expand All @@ -27,6 +25,7 @@ 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
6 changes: 6 additions & 0 deletions kzg-bench/src/benches/eip_4844.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ pub fn bench_eip_4844<
compute_kzg_proof: &dyn Fn(&[TFr], &TFr, &TKZGSettings) -> Result<(TG1, TFr), String>,
verify_kzg_proof: &dyn Fn(&TG1, &TFr, &TFr, &TG1, &TKZGSettings) -> Result<bool, String>,
compute_blob_kzg_proof: &dyn Fn(&[TFr], &TG1, &TKZGSettings) -> Result<TG1, String>,
compute_cells_and_kzg_proofs: &dyn Fn(&[u8], &TKZGSettings) -> Result<(Vec<Vec<TFr>>, Vec<TG1>), String>,
verify_blob_kzg_proof: &dyn Fn(&[TFr], &TG1, &TG1, &TKZGSettings) -> Result<bool, String>,
verify_blob_kzg_proof_batch: &dyn Fn(
&[Vec<TFr>],
Expand Down Expand Up @@ -100,6 +101,11 @@ pub fn bench_eip_4844<
})
});

c.bench_function("compute_cells_and_kzg_proofs", |b| {
let blob_bytes = generate_random_blob_bytes(&mut rng);
b.iter(|| compute_cells_and_kzg_proofs(&blob_bytes, &ts))
});

let mut group = c.benchmark_group("verify_blob_kzg_proof_batch");
for count in [1, 2, 4, 8, 16, 32, 64] {
group.throughput(Throughput::Elements(count as u64));
Expand Down
16 changes: 16 additions & 0 deletions kzg/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,21 @@ edition = "2021"

[dependencies]
blst = "0.3.11"
hex = "0.4.3"
sha2 = { version = "0.10.6", default-features = false }
num_cpus = { version = "1.16.0", optional = true }
rayon = { version = "1.8.0", optional = true }
threadpool = { version = "^1.8.1", optional = true }
siphasher = { version = "1.0.0", default-features = false }
ark-std = { version = "^0.4.0", default-features = false }
ark-ec = { version = "^0.4.2", default-features = false }
ark-poly = { version = "^0.4.2", default-features = false }
ark-ff = { version = "^0.4.2", default-features = false, features = [ "asm" ] }
ark-bls12-381 = { version = "^0.4.0", default-features = false, features = [ "curve" ] }
ark-serialize = { version = "^0.4.2", default-features = false }
icicle-bls12-381 = { git = "https://github.com/ArtiomTr/icicle.git", rev = "2942ad9f9894119f0204325e08ddb55b8a8de227", version = "1.9.1", optional = true }
icicle-core = { git = "https://github.com/ArtiomTr/icicle.git", rev = "2942ad9f9894119f0204325e08ddb55b8a8de227", version = "1.9.1", optional = true }
icicle-cuda-runtime = { git = "https://github.com/ArtiomTr/icicle.git", rev = "2942ad9f9894119f0204325e08ddb55b8a8de227", version = "1.9.1", optional = true }

[features]
default = [
Expand All @@ -29,3 +39,9 @@ std = [
rand = []
arkmsm = []
bgmw = []
cuda = [
"parallel",
"dep:icicle-bls12-381",
"dep:icicle-core",
"dep:icicle-cuda-runtime"
]
109 changes: 107 additions & 2 deletions kzg/src/eip_4844.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,25 @@ use alloc::string::ToString;
use alloc::sync::Arc;
use alloc::vec;
use alloc::vec::Vec;

// use sha2::digest::generic_array::sequence;
// use core::cell;
// use core::result;
pub use blst::{blst_fr, blst_p1, blst_p2};
use core::ffi::c_uint;
use core::hash::Hash;
use core::hash::Hasher;
use sha2::{Digest, Sha256};
use siphasher::sip::SipHasher;

// use crate::kzg::{FFTFr, Fr};
use crate::common_utils::reverse_bit_order;
use crate::msm::precompute::PrecomputationTable;
use crate::FFTFr;
use crate::G1Affine;
use crate::G1Fp;
use crate::G1GetFp;
use crate::G1LinComb;
use crate::{FFTSettings, Fr, G1Mul, KZGSettings, PairingVerify, Poly, G1, G2};
use crate::fk20_proofs::compute_fk20_proofs;

#[cfg(feature = "parallel")]
use rayon::prelude::*;
Expand Down Expand Up @@ -57,6 +61,14 @@ pub const RANDOM_CHALLENGE_KZG_BATCH_DOMAIN: [u8; 16] = [
82, 67, 75, 90, 71, 66, 65, 84, 67, 72, 95, 95, 95, 86, 49, 95,
]; // "RCKZGBATCH___V1_"

////////////////////////////// Constant values for EIP-7594 //////////////////////////////
pub const FIELD_ELEMENTS_PER_EXT_BLOB: usize = 2 * FIELD_ELEMENTS_PER_BLOB;
pub const FIELD_ELEMENTS_PER_CELL: usize = 64;
pub const BYTES_PER_CELL: usize = FIELD_ELEMENTS_PER_CELL * BYTES_PER_FIELD_ELEMENT;
pub const CELLS_PER_EXT_BLOB: usize = FIELD_ELEMENTS_PER_EXT_BLOB / FIELD_ELEMENTS_PER_CELL;
pub const RANDOM_CHALLENGE_KZG_CELL_BATCH_DOMAIN: [u8; 32] = [82, 67, 95, 86, 69, 82, 73, 70, 89, 95, 67, 69, 76, 76, 95, 75,
90, 71, 95, 80, 82, 79, 79, 70, 95, 66, 65, 84, 67, 72, 95, 86,]; // "b'RCKZGCBATCH__V1_'"

////////////////////////////// C API for EIP-4844 //////////////////////////////

pub type C_KZG_RET = c_uint;
Expand Down Expand Up @@ -92,10 +104,19 @@ pub struct KZGCommitment {
}

#[repr(C)]
#[derive(Clone)]
pub struct KZGProof {
pub bytes: [u8; BYTES_PER_PROOF],
}

impl Default for KZGProof {
fn default() -> Self {
KZGProof {
bytes: [0; BYTES_PER_PROOF],
}
}
}

#[repr(C)]
pub struct CKZGSettings {
pub max_width: u64,
Expand All @@ -104,6 +125,29 @@ pub struct CKZGSettings {
pub g2_values: *mut blst_p2,
}

#[repr(C)]
#[derive(Clone)]
pub struct Cell {
bytes: [u8; BYTES_PER_CELL],
}

impl Default for Cell {
fn default() -> Self {
Cell {
bytes: [0; BYTES_PER_CELL],
}
}
}

impl Cell {
pub fn to_bytes(&self) -> &[u8; BYTES_PER_CELL] {
&self.bytes
}
}

#[repr(C)]
pub struct CellIndex(u64);

pub struct PrecomputationTableManager<TFr, TG1, TG1Fp, TG1Affine>
where
TFr: Fr,
Expand Down Expand Up @@ -712,6 +756,7 @@ pub fn verify_blob_kzg_proof_batch_rust<
}
}


#[allow(clippy::useless_conversion)]
pub fn bytes_to_blob<TFr: Fr>(bytes: &[u8]) -> Result<Vec<TFr>, String> {
if bytes.len() != BYTES_PER_BLOB {
Expand Down Expand Up @@ -914,3 +959,63 @@ pub fn load_trusted_setup_rust<
reverse_bit_order(&mut g1_values)?;
TKZGSettings::new(g1_values.as_slice(), g2_values.as_slice(), max_scale, &fs)
}

////////////////////////////// Trait based implementations of functions for EIP-7594 //////////////////////////////
#[no_mangle]
pub extern "C" fn compute_cells_and_kzg_proofs_rust<
TFr: Fr,
TPoly: Poly<TFr>,
TG1: G1 + G1Mul<TFr> + G1GetFp<TG1Fp> + PairingVerify<TG1, TG2> + Default,
TG2: G2,
TG1Fp: G1Fp,
TG1Affine: G1Affine<TG1, TG1Fp>,
TFFTSettings: FFTSettings<TFr> + FFTFr<TFr>,
TKZGSettings: KZGSettings<TFr, TG1, TG2, TFFTSettings, TPoly, TG1Fp, TG1Affine>,
>(
blob: &[TFr],
s: &TKZGSettings,
) -> Result<
(
Vec<Cell>,
Vec<KZGProof>
), String>{
// Ensure blob length is equal to Bytes per blob
if blob.len() != BYTES_PER_BLOB {
return Err(String::from("Blob length must be BYTES_PER_BLOB"));
}
// Convert the blob to a polynomial.
let polynomial: TPoly = blob_to_polynomial(blob)?;

// Allocate arrays to hold cells and proofs
let mut cells = vec![Cell::default(); CELLS_PER_EXT_BLOB];
let mut proofs = vec![KZGProof::default(); CELLS_PER_EXT_BLOB];

// Compute cells
let mut data_fr = vec![TFr::zero(); FIELD_ELEMENTS_PER_EXT_BLOB];

// Perform FFT on the polynomial
data_fr = s.get_fft_settings().fft_fr(&polynomial.get_coeffs(), false)?;

// Perform bit reversal permutation
reverse_bit_order(&mut data_fr)?;

// Covert field elements to cell bytes
for (i, cell) in cells.iter_mut().enumerate() {
let mut cell_data = Vec::new();
for j in 0..FIELD_ELEMENTS_PER_CELL {
let index = i * FIELD_ELEMENTS_PER_CELL + j;
let fr_bytes = data_fr[index].to_bytes();
cell_data.extend_from_slice(&fr_bytes);
}
let cell_bytes = cell.to_bytes();
}

// Compute proofs
// let mut proofs_g1 = vec![TG1::identity(); CELLS_PER_EXT_BLOB];
let mut proofs_g1 = compute_fk20_proofs::<TFr, TG1, TG2, TFFTSettings, TPoly, TG1Fp, TG1Affine, TKZGSettings, TG1>(&polynomial.get_coeffs(), FIELD_ELEMENTS_PER_BLOB, s)?;
reverse_bit_order(&mut proofs_g1)?;

Ok((cells, proofs))
}


Loading