Skip to content
Closed
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
1 change: 0 additions & 1 deletion basic_system/src/cost_constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,4 @@ pub const BN254_PAIRING_BASE_NATIVE_COST: u64 = native_with_delegations!(13_000_
pub const BN254_PAIRING_PER_PAIR_NATIVE_COST: u64 = BN254_PAIRING_BASE_NATIVE_COST;
pub const MODEXP_WORST_CASE_NATIVE_PER_GAS: u64 = 300;
pub const P256_NATIVE_COST: u64 = native_with_delegations!(500_000, 71_000, 0);
// TODO(EVM-1178) Add more vectors and benchmark cost better
pub const POINT_EVALUATION_NATIVE_COST: u64 = native_with_delegations!(49_900_000, 3_301_000, 0);
129 changes: 128 additions & 1 deletion basic_system/src/system_functions/point_evaluation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ mod tests {
use std::alloc::Global;
use zk_ee::reference_implementations::BaseResources;
use zk_ee::reference_implementations::DecreasingNative;
use zk_ee::system::Resource;
use zk_ee::system::{Computational, Resource};

use alloy_primitives::hex;

Expand All @@ -150,6 +150,133 @@ mod tests {
TestResources::FORMAL_INFINITE
}

fn valid_point_evaluation_input() -> Vec<u8> {
// Test data from:
// https://github.com/ethereum/c-kzg-4844/blob/main/tests/verify_kzg_proof/kzg-mainnet/verify_kzg_proof_case_correct_proof_4_4/data.yaml
let commitment = hex!(
"8f59a8d2a1a625a17f3fea0fe5eb8c896db3764f3185481bc22f91b4aaffcca25f26936857bc3a7c2539ea8ec3a952b7"
);
let z = hex!("73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000000");
let y = hex!("1522a4a7f34e1ea350ae07c29c96c7e79655aa926122e95fe69fcbd932ca49e9");
let proof = hex!(
"a62ad71d14c5719385c0686f1871430475bf3a00f0aa3f7b8dd99a9abc2160744faf0070725e00b60ad9a026a15b1a8c"
);
let versioned_hash = versioned_hash_for_kzg(&commitment);

[
versioned_hash.as_slice(),
z.as_slice(),
y.as_slice(),
commitment.as_slice(),
proof.as_slice(),
]
.concat()
}

fn assert_cost_vector(
input: &[u8],
expected_error: Option<PointEvaluationInterfaceError>,
expected_output: Option<&[u8]>,
) {
let mut output = Vec::new();
let mut resources = infinite_resources();
let ergs_before = resources.ergs().0;
let native_before = resources.native().as_u64();

let result = PointEvaluationImpl::execute(input, &mut output, &mut resources, Global);

match (expected_error, result) {
(None, Ok(())) => {
let expected_output = expected_output.expect("expected output must be set");
assert_eq!(output.as_slice(), expected_output);
}
(Some(expected), Err(SubsystemError::LeafUsage(err))) => {
assert_eq!(err.0, expected);
assert!(output.is_empty());
}
(_, other) => panic!("Unexpected result: {other:?}"),
}

assert_eq!(
ergs_before - resources.ergs().0,
POINT_EVALUATION_COST_ERGS.0
);
assert_eq!(
native_before - resources.native().as_u64(),
POINT_EVALUATION_NATIVE_COST
);
}

#[test]
fn test_point_evaluation_cost_vectors() {
let valid_input = valid_point_evaluation_input();
assert_cost_vector(
&valid_input,
None,
Some(&POINT_EVAL_PRECOMPILE_SUCCESS_RESPONSE),
);

// Invalid input size
assert_cost_vector(
&vec![0u8; 191],
Comment on lines +220 to +221
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

&vec![0u8; 191] allocates a Vec just to pass a slice. Consider using a fixed-size byte array/slice (e.g., &[0u8; 191]) or binding the Vec to a local variable before borrowing, to avoid an unnecessary heap allocation in this test.

Suggested change
assert_cost_vector(
&vec![0u8; 191],
let invalid_input_too_short = [0u8; 191];
assert_cost_vector(
&invalid_input_too_short,

Copilot uses AI. Check for mistakes.
Some(PointEvaluationInterfaceError::InvalidInputSize),
None,
);

// Invalid versioned hash
let mut invalid_versioned_hash = valid_input.clone();
invalid_versioned_hash[0] ^= 0x01;
assert_cost_vector(
&invalid_versioned_hash,
Some(PointEvaluationInterfaceError::InvalidVersionedHash),
None,
);

// Invalid commitment point encoding (versioned hash adjusted to reach point parsing)
let mut invalid_commitment = valid_input.clone();
let invalid_commitment_point = [0u8; 48];
invalid_commitment[96..144].copy_from_slice(&invalid_commitment_point);
let adjusted_hash = versioned_hash_for_kzg(&invalid_commitment_point);
invalid_commitment[0..32].copy_from_slice(&adjusted_hash);
assert_cost_vector(
&invalid_commitment,
Some(PointEvaluationInterfaceError::InvalidPoint),
None,
);

// Invalid proof point encoding
let mut invalid_proof = valid_input.clone();
invalid_proof[144..192].fill(0);
assert_cost_vector(
&invalid_proof,
Some(PointEvaluationInterfaceError::InvalidPoint),
None,
);

// Invalid scalar z (z = modulus)
let mut invalid_scalar_z = valid_input.clone();
let modulus = [
0x73, 0xed, 0xa7, 0x53, 0x29, 0x9d, 0x7d, 0x48, 0x33, 0x39, 0xd8, 0x08, 0x09, 0xa1,
0xd8, 0x05, 0x53, 0xbd, 0xa4, 0x02, 0xff, 0xfe, 0x5b, 0xfe, 0xff, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x01,
];
invalid_scalar_z[32..64].copy_from_slice(&modulus);
Comment on lines +258 to +263
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The BLS12-381 scalar field modulus byte array is duplicated here (and also appears in other tests in this module, e.g. test_point_evaluation_invalid_scalar_z). Consider factoring it into a shared const/helper to avoid divergence if the value ever needs to change or be reused elsewhere.

Copilot uses AI. Check for mistakes.
assert_cost_vector(
&invalid_scalar_z,
Some(PointEvaluationInterfaceError::InvalidScalar),
None,
);

// Pairing mismatch with otherwise valid input
let mut pairing_mismatch = valid_input;
pairing_mismatch[95] ^= 0x01;
assert_cost_vector(
&pairing_mismatch,
Some(PointEvaluationInterfaceError::PairingMismatch),
None,
);
}

#[test]
fn basic_test() {
// Test data from: https://github.com/ethereum/c-kzg-4844/blob/main/tests/verify_kzg_proof/kzg-mainnet/verify_kzg_proof_case_correct_proof_4_4/data.yaml
Expand Down
Loading