Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions crates/precompile/src/kzg_point_evaluation/arkworks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use ark_ec::{AffineRepr, CurveGroup};
use ark_ff::{BigInteger, PrimeField};
use ark_serialize::CanonicalDeserialize;
use core::ops::Neg;
use primitives::OnceLock;

/// Verify KZG proof using BLS12-381 implementation.
///
Expand Down Expand Up @@ -52,7 +53,7 @@ pub fn verify_kzg_proof(

// Compute X_minus_z = [τ]G₂ - [z]G₂
let z_g2 = p2_scalar_mul(&g2, &z_fr);
let x_minus_z = p2_sub_affine(&tau_g2, &z_g2);
let x_minus_z = p2_sub_affine(tau_g2, &z_g2);

// Verify: P - y = Q * (X - z)
// Using pairing check: e(P - y, -G₂) * e(proof, X - z) == 1
Expand All @@ -63,11 +64,14 @@ pub fn verify_kzg_proof(

/// Get the trusted setup G2 point `[τ]₂` from the Ethereum KZG ceremony.
/// This is g2_monomial_1 from trusted_setup_4096.json
fn get_trusted_setup_g2() -> G2Affine {
// Parse the compressed G2 point using unchecked deserialization since we trust this point
// This should never fail since we're using a known valid point from the trusted setup
G2Affine::deserialize_compressed_unchecked(&TRUSTED_SETUP_TAU_G2_BYTES[..])
.expect("Failed to parse trusted setup G2 point")
fn get_trusted_setup_g2() -> &'static G2Affine {
static TAU_G2: OnceLock<G2Affine> = OnceLock::new();
TAU_G2.get_or_init(|| {
// Parse the compressed G2 point using unchecked deserialization since we trust this point
// This should never fail since we're using a known valid point from the trusted setup
G2Affine::deserialize_compressed_unchecked(&TRUSTED_SETUP_TAU_G2_BYTES[..])
.expect("Failed to parse trusted setup G2 point")
})
}

/// Parse a G1 point from compressed format (48 bytes)
Expand Down
29 changes: 17 additions & 12 deletions crates/precompile/src/kzg_point_evaluation/blst.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use ::blst::{
blst_p1_affine, blst_p1_affine_in_g1, blst_p1_affine_on_curve, blst_p2_affine, blst_scalar,
blst_scalar_fr_check, blst_scalar_from_bendian,
};
use primitives::OnceLock;

/// Verify KZG proof using BLST BLS12-381 implementation.
///
Expand Down Expand Up @@ -54,7 +55,7 @@ pub fn verify_kzg_proof(

// Compute X_minus_z = [τ]G₂ - [z]G₂
let z_g2 = p2_scalar_mul(&g2, &z_scalar);
let x_minus_z = p2_sub_affine(&tau_g2, &z_g2);
let x_minus_z = p2_sub_affine(tau_g2, &z_g2);

// Verify: P - y = Q * (X - z)
// Using pairing check: e(P - y, -G₂) * e(proof, X - z) == 1
Expand All @@ -65,18 +66,22 @@ pub fn verify_kzg_proof(

/// Get the trusted setup G2 point `[τ]₂` from the Ethereum KZG ceremony.
/// This is g2_monomial_1 from trusted_setup_4096.json
fn get_trusted_setup_g2() -> blst_p2_affine {
// For compressed G2, we need to decompress
let mut g2_affine = blst_p2_affine::default();
unsafe {
// The compressed format has x coordinate and a flag bit for y
// We use uncompress which handles this automatically
let result = blst::blst_p2_uncompress(&mut g2_affine, TRUSTED_SETUP_TAU_G2_BYTES.as_ptr());
if result != blst::BLST_ERROR::BLST_SUCCESS {
panic!("Failed to deserialize trusted setup G2 point");
fn get_trusted_setup_g2() -> &'static blst_p2_affine {
static TAU_G2: OnceLock<blst_p2_affine> = OnceLock::new();
TAU_G2.get_or_init(|| {
// For compressed G2, we need to decompress
let mut g2_affine = blst_p2_affine::default();
unsafe {
// The compressed format has x coordinate and a flag bit for y
// We use uncompress which handles this automatically
let result =
blst::blst_p2_uncompress(&mut g2_affine, TRUSTED_SETUP_TAU_G2_BYTES.as_ptr());
if result != blst::BLST_ERROR::BLST_SUCCESS {
panic!("Failed to deserialize trusted setup G2 point");
}
}
}
g2_affine
g2_affine
})
}

/// Get G1 generator point
Expand Down
Loading