2023-03-02 20:49:10 +00:00
|
|
|
"""
|
2024-04-24 16:40:27 +00:00
|
|
|
KZG test vectors generator for EIP-4844
|
2023-03-02 20:49:10 +00:00
|
|
|
"""
|
|
|
|
|
|
|
|
from typing import Tuple, Iterable, Any, Callable, Dict
|
|
|
|
|
2024-04-24 16:40:27 +00:00
|
|
|
from eth_utils import encode_hex
|
2023-03-02 20:49:10 +00:00
|
|
|
|
2024-04-24 16:40:27 +00:00
|
|
|
from eth2spec.deneb import spec
|
|
|
|
from eth2spec.gen_helpers.gen_base import gen_runner, gen_typing
|
2023-03-02 20:49:10 +00:00
|
|
|
from eth2spec.test.helpers.constants import DENEB
|
|
|
|
from eth2spec.test.helpers.typing import SpecForkName
|
2024-04-24 16:40:27 +00:00
|
|
|
from eth2spec.test.utils.kzg_tests import (
|
|
|
|
BLOB_ALL_TWOS,
|
|
|
|
BLOB_ALL_ZEROS,
|
|
|
|
BLOB_RANDOM_VALID1,
|
|
|
|
G1,
|
|
|
|
INVALID_BLOBS,
|
|
|
|
INVALID_FIELD_ELEMENTS,
|
|
|
|
INVALID_G1_POINTS,
|
|
|
|
VALID_BLOBS,
|
|
|
|
VALID_FIELD_ELEMENTS,
|
|
|
|
bls_add_one,
|
|
|
|
encode_hex_list,
|
|
|
|
expect_exception,
|
|
|
|
field_element_bytes,
|
|
|
|
hash,
|
|
|
|
)
|
|
|
|
from eth2spec.utils import bls
|
2023-03-02 20:49:10 +00:00
|
|
|
|
|
|
|
|
2024-04-24 16:40:27 +00:00
|
|
|
###############################################################################
|
|
|
|
# Test cases for blob_to_kzg_commitment
|
|
|
|
###############################################################################
|
2023-03-02 20:49:10 +00:00
|
|
|
|
|
|
|
def case01_blob_to_kzg_commitment():
|
|
|
|
# Valid cases
|
|
|
|
for blob in VALID_BLOBS:
|
|
|
|
commitment = spec.blob_to_kzg_commitment(blob)
|
|
|
|
identifier = f'{encode_hex(hash(blob))}'
|
|
|
|
yield f'blob_to_kzg_commitment_case_valid_blob_{(hash(bytes(identifier, "utf-8"))[:8]).hex()}', {
|
|
|
|
'input': {
|
|
|
|
'blob': encode_hex(blob),
|
|
|
|
},
|
|
|
|
'output': encode_hex(commitment)
|
|
|
|
}
|
|
|
|
|
|
|
|
# Edge case: Invalid blobs
|
|
|
|
for blob in INVALID_BLOBS:
|
|
|
|
identifier = f'{encode_hex(hash(blob))}'
|
|
|
|
expect_exception(spec.blob_to_kzg_commitment, blob)
|
|
|
|
yield f'blob_to_kzg_commitment_case_invalid_blob_{(hash(bytes(identifier, "utf-8"))[:8]).hex()}', {
|
|
|
|
'input': {
|
|
|
|
'blob': encode_hex(blob)
|
|
|
|
},
|
|
|
|
'output': None
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2024-04-24 16:40:27 +00:00
|
|
|
###############################################################################
|
|
|
|
# Test cases for compute_kzg_proof
|
|
|
|
###############################################################################
|
|
|
|
|
2023-03-02 20:49:10 +00:00
|
|
|
def case02_compute_kzg_proof():
|
|
|
|
# Valid cases
|
|
|
|
for blob in VALID_BLOBS:
|
2023-03-07 21:56:55 +00:00
|
|
|
for z in VALID_FIELD_ELEMENTS:
|
2023-03-07 17:50:56 +00:00
|
|
|
proof, y = spec.compute_kzg_proof(blob, z)
|
2023-03-02 20:49:10 +00:00
|
|
|
identifier = f'{encode_hex(hash(blob))}_{encode_hex(z)}'
|
|
|
|
yield f'compute_kzg_proof_case_valid_blob_{(hash(bytes(identifier, "utf-8"))[:8]).hex()}', {
|
|
|
|
'input': {
|
|
|
|
'blob': encode_hex(blob),
|
|
|
|
'z': encode_hex(z),
|
|
|
|
},
|
2023-03-07 17:50:56 +00:00
|
|
|
'output': (encode_hex(proof), encode_hex(y))
|
2023-03-02 20:49:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
# Edge case: Invalid blobs
|
|
|
|
for blob in INVALID_BLOBS:
|
2023-03-07 21:56:55 +00:00
|
|
|
z = VALID_FIELD_ELEMENTS[0]
|
2023-03-02 20:49:10 +00:00
|
|
|
expect_exception(spec.compute_kzg_proof, blob, z)
|
2023-05-02 15:57:49 +00:00
|
|
|
identifier = f'{encode_hex(hash(blob))}'
|
2023-03-02 20:49:10 +00:00
|
|
|
yield f'compute_kzg_proof_case_invalid_blob_{(hash(bytes(identifier, "utf-8"))[:8]).hex()}', {
|
|
|
|
'input': {
|
|
|
|
'blob': encode_hex(blob),
|
|
|
|
'z': encode_hex(z),
|
|
|
|
},
|
|
|
|
'output': None
|
|
|
|
}
|
|
|
|
|
|
|
|
# Edge case: Invalid z
|
2023-03-07 21:56:55 +00:00
|
|
|
for z in INVALID_FIELD_ELEMENTS:
|
2023-03-02 20:49:10 +00:00
|
|
|
blob = VALID_BLOBS[4]
|
|
|
|
expect_exception(spec.compute_kzg_proof, blob, z)
|
2023-05-02 15:57:49 +00:00
|
|
|
identifier = f'{encode_hex(hash(z))}'
|
2023-03-02 20:49:10 +00:00
|
|
|
yield f'compute_kzg_proof_case_invalid_z_{(hash(bytes(identifier, "utf-8"))[:8]).hex()}', {
|
|
|
|
'input': {
|
|
|
|
'blob': encode_hex(blob),
|
|
|
|
'z': encode_hex(z),
|
|
|
|
},
|
|
|
|
'output': None
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2024-04-24 16:40:27 +00:00
|
|
|
###############################################################################
|
|
|
|
# Test cases for verify_kzg_proof
|
|
|
|
###############################################################################
|
|
|
|
|
2023-03-02 20:49:10 +00:00
|
|
|
def case03_verify_kzg_proof():
|
|
|
|
# Valid cases
|
|
|
|
for blob in VALID_BLOBS:
|
2023-03-07 21:56:55 +00:00
|
|
|
for z in VALID_FIELD_ELEMENTS:
|
2023-03-07 17:50:56 +00:00
|
|
|
proof, y = spec.compute_kzg_proof(blob, z)
|
2023-03-02 20:49:10 +00:00
|
|
|
commitment = spec.blob_to_kzg_commitment(blob)
|
|
|
|
assert spec.verify_kzg_proof(commitment, z, y, proof)
|
|
|
|
identifier = f'{encode_hex(hash(blob))}_{encode_hex(z)}'
|
|
|
|
yield f'verify_kzg_proof_case_correct_proof_{(hash(bytes(identifier, "utf-8"))[:8]).hex()}', {
|
|
|
|
'input': {
|
|
|
|
'commitment': encode_hex(commitment),
|
|
|
|
'z': encode_hex(z),
|
|
|
|
'y': encode_hex(y),
|
|
|
|
'proof': encode_hex(proof),
|
|
|
|
},
|
|
|
|
'output': True
|
|
|
|
}
|
|
|
|
|
|
|
|
# Incorrect proofs
|
|
|
|
for blob in VALID_BLOBS:
|
2023-03-07 21:56:55 +00:00
|
|
|
for z in VALID_FIELD_ELEMENTS:
|
2023-03-07 17:50:56 +00:00
|
|
|
proof_orig, y = spec.compute_kzg_proof(blob, z)
|
|
|
|
proof = bls_add_one(proof_orig)
|
2023-03-02 20:49:10 +00:00
|
|
|
commitment = spec.blob_to_kzg_commitment(blob)
|
|
|
|
assert not spec.verify_kzg_proof(commitment, z, y, proof)
|
|
|
|
identifier = f'{encode_hex(hash(blob))}_{encode_hex(z)}'
|
|
|
|
yield f'verify_kzg_proof_case_incorrect_proof_{(hash(bytes(identifier, "utf-8"))[:8]).hex()}', {
|
|
|
|
'input': {
|
|
|
|
'commitment': encode_hex(commitment),
|
|
|
|
'z': encode_hex(z),
|
|
|
|
'y': encode_hex(y),
|
|
|
|
'proof': encode_hex(proof),
|
|
|
|
},
|
|
|
|
'output': False
|
|
|
|
}
|
|
|
|
|
2023-09-19 16:39:47 +00:00
|
|
|
# Incorrect `G1_POINT_AT_INFINITY` proof
|
|
|
|
blob = BLOB_RANDOM_VALID1
|
2023-09-22 12:07:55 +00:00
|
|
|
for z in VALID_FIELD_ELEMENTS:
|
|
|
|
_, y = spec.compute_kzg_proof(blob, z)
|
|
|
|
commitment = spec.blob_to_kzg_commitment(blob)
|
|
|
|
proof = spec.G1_POINT_AT_INFINITY
|
|
|
|
assert not spec.verify_kzg_proof(commitment, z, y, proof)
|
2023-09-25 09:43:31 +00:00
|
|
|
prefix = 'verify_kzg_proof_case_incorrect_proof_point_at_infinity'
|
2023-09-22 12:07:55 +00:00
|
|
|
identifier = f'{encode_hex(hash(blob))}_{encode_hex(z)}'
|
2023-09-25 09:43:31 +00:00
|
|
|
yield f'{prefix}_{(hash(bytes(identifier, "utf-8"))[:8]).hex()}', {
|
2023-09-22 12:07:55 +00:00
|
|
|
'input': {
|
|
|
|
'commitment': encode_hex(commitment),
|
|
|
|
'z': encode_hex(z),
|
|
|
|
'y': encode_hex(y),
|
|
|
|
'proof': encode_hex(proof),
|
|
|
|
},
|
|
|
|
'output': False
|
|
|
|
}
|
|
|
|
|
|
|
|
# Correct `G1_POINT_AT_INFINITY` proof for zero poly
|
|
|
|
blob = BLOB_ALL_ZEROS
|
|
|
|
for z in VALID_FIELD_ELEMENTS:
|
|
|
|
_, y = spec.compute_kzg_proof(blob, z)
|
|
|
|
commitment = spec.blob_to_kzg_commitment(blob)
|
|
|
|
proof = spec.G1_POINT_AT_INFINITY
|
|
|
|
assert spec.verify_kzg_proof(commitment, z, y, proof)
|
2023-09-25 09:43:31 +00:00
|
|
|
prefix = 'verify_kzg_proof_case_correct_proof_point_at_infinity_for_zero_poly'
|
2023-09-22 12:07:55 +00:00
|
|
|
identifier = f'{encode_hex(hash(blob))}_{encode_hex(z)}'
|
2023-09-25 09:43:31 +00:00
|
|
|
yield f'{prefix}_{(hash(bytes(identifier, "utf-8"))[:8]).hex()}', {
|
2023-09-22 12:07:55 +00:00
|
|
|
'input': {
|
|
|
|
'commitment': encode_hex(commitment),
|
|
|
|
'z': encode_hex(z),
|
|
|
|
'y': encode_hex(y),
|
|
|
|
'proof': encode_hex(proof),
|
|
|
|
},
|
|
|
|
'output': True
|
|
|
|
}
|
|
|
|
|
|
|
|
# Correct `G1_POINT_AT_INFINITY` proof for poly of all twos
|
|
|
|
blob = BLOB_ALL_TWOS
|
|
|
|
for z in VALID_FIELD_ELEMENTS:
|
|
|
|
_, y = spec.compute_kzg_proof(blob, z)
|
|
|
|
commitment = spec.blob_to_kzg_commitment(blob)
|
|
|
|
proof = spec.G1_POINT_AT_INFINITY
|
|
|
|
assert spec.verify_kzg_proof(commitment, z, y, proof)
|
|
|
|
assert y == field_element_bytes(2)
|
2023-09-25 09:43:31 +00:00
|
|
|
prefix = 'verify_kzg_proof_case_correct_proof_point_at_infinity_for_twos_poly'
|
2023-09-22 12:07:55 +00:00
|
|
|
identifier = f'{encode_hex(hash(blob))}_{encode_hex(z)}'
|
2023-09-25 09:43:31 +00:00
|
|
|
yield f'{prefix}_{(hash(bytes(identifier, "utf-8"))[:8]).hex()}', {
|
2023-09-22 12:07:55 +00:00
|
|
|
'input': {
|
|
|
|
'commitment': encode_hex(commitment),
|
|
|
|
'z': encode_hex(z),
|
|
|
|
'y': encode_hex(y),
|
|
|
|
'proof': encode_hex(proof),
|
|
|
|
},
|
|
|
|
'output': True
|
|
|
|
}
|
2023-09-19 16:39:47 +00:00
|
|
|
|
2023-05-02 15:57:49 +00:00
|
|
|
# Edge case: Invalid commitment
|
|
|
|
for commitment in INVALID_G1_POINTS:
|
|
|
|
blob, z = VALID_BLOBS[2], VALID_FIELD_ELEMENTS[1]
|
|
|
|
proof, y = spec.compute_kzg_proof(blob, z)
|
|
|
|
expect_exception(spec.verify_kzg_proof, commitment, z, y, proof)
|
|
|
|
identifier = f'{encode_hex(commitment)}'
|
|
|
|
yield f'verify_kzg_proof_case_invalid_commitment_{(hash(bytes(identifier, "utf-8"))[:8]).hex()}', {
|
|
|
|
'input': {
|
|
|
|
'commitment': encode_hex(commitment),
|
|
|
|
'z': encode_hex(z),
|
|
|
|
'y': encode_hex(y),
|
|
|
|
'proof': encode_hex(proof),
|
|
|
|
},
|
|
|
|
'output': None
|
|
|
|
}
|
|
|
|
|
2023-03-02 20:49:10 +00:00
|
|
|
# Edge case: Invalid z
|
2023-03-07 21:56:55 +00:00
|
|
|
for z in INVALID_FIELD_ELEMENTS:
|
|
|
|
blob, validz = VALID_BLOBS[4], VALID_FIELD_ELEMENTS[1]
|
2023-03-07 17:50:56 +00:00
|
|
|
proof, y = spec.compute_kzg_proof(blob, validz)
|
2023-03-02 20:49:10 +00:00
|
|
|
commitment = spec.blob_to_kzg_commitment(blob)
|
|
|
|
expect_exception(spec.verify_kzg_proof, commitment, z, y, proof)
|
2023-05-02 15:57:49 +00:00
|
|
|
identifier = f'{encode_hex(z)}'
|
2023-03-02 20:49:10 +00:00
|
|
|
yield f'verify_kzg_proof_case_invalid_z_{(hash(bytes(identifier, "utf-8"))[:8]).hex()}', {
|
|
|
|
'input': {
|
|
|
|
'commitment': encode_hex(commitment),
|
|
|
|
'z': encode_hex(z),
|
|
|
|
'y': encode_hex(y),
|
|
|
|
'proof': encode_hex(proof),
|
|
|
|
},
|
|
|
|
'output': None
|
|
|
|
}
|
|
|
|
|
|
|
|
# Edge case: Invalid y
|
2023-03-07 21:56:55 +00:00
|
|
|
for y in INVALID_FIELD_ELEMENTS:
|
|
|
|
blob, z = VALID_BLOBS[4], VALID_FIELD_ELEMENTS[1]
|
|
|
|
proof, _ = spec.compute_kzg_proof(blob, z)
|
|
|
|
commitment = spec.blob_to_kzg_commitment(blob)
|
|
|
|
expect_exception(spec.verify_kzg_proof, commitment, z, y, proof)
|
2023-05-02 15:57:49 +00:00
|
|
|
identifier = f'{encode_hex(y)}'
|
2023-03-07 21:56:55 +00:00
|
|
|
yield f'verify_kzg_proof_case_invalid_y_{(hash(bytes(identifier, "utf-8"))[:8]).hex()}', {
|
|
|
|
'input': {
|
|
|
|
'commitment': encode_hex(commitment),
|
|
|
|
'z': encode_hex(z),
|
|
|
|
'y': encode_hex(y),
|
|
|
|
'proof': encode_hex(proof),
|
|
|
|
},
|
|
|
|
'output': None
|
|
|
|
}
|
|
|
|
|
2023-05-02 15:57:49 +00:00
|
|
|
# Edge case: Invalid proof
|
|
|
|
for proof in INVALID_G1_POINTS:
|
|
|
|
blob, z = VALID_BLOBS[2], VALID_FIELD_ELEMENTS[1]
|
|
|
|
_, y = spec.compute_kzg_proof(blob, z)
|
|
|
|
commitment = spec.blob_to_kzg_commitment(blob)
|
|
|
|
expect_exception(spec.verify_kzg_proof, commitment, z, y, proof)
|
|
|
|
identifier = f'{encode_hex(proof)}'
|
|
|
|
yield f'verify_kzg_proof_case_invalid_proof_{(hash(bytes(identifier, "utf-8"))[:8]).hex()}', {
|
|
|
|
'input': {
|
|
|
|
'commitment': encode_hex(commitment),
|
|
|
|
'z': encode_hex(z),
|
|
|
|
'y': encode_hex(y),
|
|
|
|
'proof': encode_hex(proof),
|
|
|
|
},
|
|
|
|
'output': None
|
|
|
|
}
|
2023-03-07 21:56:55 +00:00
|
|
|
|
2023-03-02 20:49:10 +00:00
|
|
|
|
2024-04-24 16:40:27 +00:00
|
|
|
###############################################################################
|
|
|
|
# Test cases for compute_blob_kzg_proof
|
|
|
|
###############################################################################
|
|
|
|
|
2023-03-02 20:49:10 +00:00
|
|
|
def case04_compute_blob_kzg_proof():
|
|
|
|
# Valid cases
|
|
|
|
for blob in VALID_BLOBS:
|
2023-03-07 17:50:56 +00:00
|
|
|
commitment = spec.blob_to_kzg_commitment(blob)
|
|
|
|
proof = spec.compute_blob_kzg_proof(blob, commitment)
|
2023-03-02 20:49:10 +00:00
|
|
|
identifier = f'{encode_hex(hash(blob))}'
|
|
|
|
yield f'compute_blob_kzg_proof_case_valid_blob_{(hash(bytes(identifier, "utf-8"))[:8]).hex()}', {
|
|
|
|
'input': {
|
|
|
|
'blob': encode_hex(blob),
|
2023-03-07 17:50:56 +00:00
|
|
|
'commitment': encode_hex(commitment),
|
2023-03-02 20:49:10 +00:00
|
|
|
},
|
|
|
|
'output': encode_hex(proof)
|
|
|
|
}
|
|
|
|
|
|
|
|
# Edge case: Invalid blob
|
|
|
|
for blob in INVALID_BLOBS:
|
2023-03-07 17:50:56 +00:00
|
|
|
commitment = G1
|
|
|
|
expect_exception(spec.compute_blob_kzg_proof, blob, commitment)
|
2023-03-02 20:49:10 +00:00
|
|
|
identifier = f'{encode_hex(hash(blob))}'
|
|
|
|
yield f'compute_blob_kzg_proof_case_invalid_blob_{(hash(bytes(identifier, "utf-8"))[:8]).hex()}', {
|
|
|
|
'input': {
|
|
|
|
'blob': encode_hex(blob),
|
2023-03-07 17:50:56 +00:00
|
|
|
'commitment': encode_hex(commitment),
|
2023-03-02 20:49:10 +00:00
|
|
|
},
|
|
|
|
'output': None
|
|
|
|
}
|
|
|
|
|
2023-05-02 15:57:49 +00:00
|
|
|
# Edge case: Invalid commitment
|
|
|
|
for commitment in INVALID_G1_POINTS:
|
|
|
|
blob = VALID_BLOBS[1]
|
|
|
|
expect_exception(spec.compute_blob_kzg_proof, blob, commitment)
|
|
|
|
identifier = f'{encode_hex(hash(commitment))}'
|
|
|
|
yield f'compute_blob_kzg_proof_case_invalid_commitment_{(hash(bytes(identifier, "utf-8"))[:8]).hex()}', {
|
|
|
|
'input': {
|
|
|
|
'blob': encode_hex(blob),
|
|
|
|
'commitment': encode_hex(commitment),
|
|
|
|
},
|
|
|
|
'output': None
|
|
|
|
}
|
2023-03-07 17:50:56 +00:00
|
|
|
|
2023-03-02 20:49:10 +00:00
|
|
|
|
2024-04-24 16:40:27 +00:00
|
|
|
###############################################################################
|
|
|
|
# Test cases for verify_blob_kzg_proof
|
|
|
|
###############################################################################
|
|
|
|
|
2023-03-02 20:49:10 +00:00
|
|
|
def case05_verify_blob_kzg_proof():
|
|
|
|
# Valid cases
|
|
|
|
for blob in VALID_BLOBS:
|
|
|
|
commitment = spec.blob_to_kzg_commitment(blob)
|
2023-03-07 17:50:56 +00:00
|
|
|
proof = spec.compute_blob_kzg_proof(blob, commitment)
|
2023-03-02 20:49:10 +00:00
|
|
|
assert spec.verify_blob_kzg_proof(blob, commitment, proof)
|
|
|
|
identifier = f'{encode_hex(hash(blob))}'
|
|
|
|
yield f'verify_blob_kzg_proof_case_correct_proof_{(hash(bytes(identifier, "utf-8"))[:8]).hex()}', {
|
|
|
|
'input': {
|
|
|
|
'blob': encode_hex(blob),
|
|
|
|
'commitment': encode_hex(commitment),
|
|
|
|
'proof': encode_hex(proof),
|
|
|
|
},
|
|
|
|
'output': True
|
|
|
|
}
|
|
|
|
|
|
|
|
# Incorrect proofs
|
|
|
|
for blob in VALID_BLOBS:
|
|
|
|
commitment = spec.blob_to_kzg_commitment(blob)
|
2023-03-07 17:50:56 +00:00
|
|
|
proof = bls_add_one(spec.compute_blob_kzg_proof(blob, commitment))
|
2023-03-02 20:49:10 +00:00
|
|
|
assert not spec.verify_blob_kzg_proof(blob, commitment, proof)
|
|
|
|
identifier = f'{encode_hex(hash(blob))}'
|
|
|
|
yield f'verify_blob_kzg_proof_case_incorrect_proof_{(hash(bytes(identifier, "utf-8"))[:8]).hex()}', {
|
|
|
|
'input': {
|
|
|
|
'blob': encode_hex(blob),
|
|
|
|
'commitment': encode_hex(commitment),
|
|
|
|
'proof': encode_hex(proof),
|
|
|
|
},
|
|
|
|
'output': False
|
|
|
|
}
|
|
|
|
|
2023-09-19 16:21:18 +00:00
|
|
|
# Incorrect `G1_POINT_AT_INFINITY` proof
|
|
|
|
blob = BLOB_RANDOM_VALID1
|
|
|
|
commitment = spec.blob_to_kzg_commitment(blob)
|
|
|
|
proof = spec.G1_POINT_AT_INFINITY
|
|
|
|
assert not spec.verify_blob_kzg_proof(blob, commitment, proof)
|
|
|
|
yield 'verify_blob_kzg_proof_case_incorrect_proof_point_at_infinity', {
|
|
|
|
'input': {
|
|
|
|
'blob': encode_hex(blob),
|
|
|
|
'commitment': encode_hex(commitment),
|
|
|
|
'proof': encode_hex(proof),
|
|
|
|
},
|
|
|
|
'output': False
|
|
|
|
}
|
|
|
|
|
2023-09-22 12:07:55 +00:00
|
|
|
# Correct `G1_POINT_AT_INFINITY` proof and commitment for zero poly
|
|
|
|
blob = BLOB_ALL_ZEROS
|
|
|
|
commitment = spec.blob_to_kzg_commitment(blob)
|
|
|
|
proof = spec.G1_POINT_AT_INFINITY
|
|
|
|
assert commitment == spec.G1_POINT_AT_INFINITY
|
|
|
|
assert spec.verify_blob_kzg_proof(blob, commitment, proof)
|
|
|
|
yield 'verify_blob_kzg_proof_case_correct_proof_point_at_infinity_for_zero_poly', {
|
|
|
|
'input': {
|
|
|
|
'blob': encode_hex(blob),
|
|
|
|
'commitment': encode_hex(commitment),
|
|
|
|
'proof': encode_hex(proof),
|
|
|
|
},
|
|
|
|
'output': True
|
|
|
|
}
|
|
|
|
|
|
|
|
# Correct `G1_POINT_AT_INFINITY` proof for all twos poly
|
|
|
|
blob = BLOB_ALL_TWOS
|
|
|
|
commitment = spec.blob_to_kzg_commitment(blob)
|
|
|
|
proof = spec.G1_POINT_AT_INFINITY
|
|
|
|
assert commitment != spec.G1_POINT_AT_INFINITY
|
|
|
|
assert spec.verify_blob_kzg_proof(blob, commitment, proof)
|
|
|
|
yield 'verify_blob_kzg_proof_case_correct_proof_point_at_infinity_for_twos_poly', {
|
|
|
|
'input': {
|
|
|
|
'blob': encode_hex(blob),
|
|
|
|
'commitment': encode_hex(commitment),
|
|
|
|
'proof': encode_hex(proof),
|
|
|
|
},
|
|
|
|
'output': True
|
|
|
|
}
|
|
|
|
|
2023-03-02 20:49:10 +00:00
|
|
|
# Edge case: Invalid blob
|
|
|
|
for blob in INVALID_BLOBS:
|
|
|
|
proof = G1
|
|
|
|
commitment = G1
|
|
|
|
expect_exception(spec.verify_blob_kzg_proof, blob, commitment, proof)
|
|
|
|
identifier = f'{encode_hex(hash(blob))}'
|
|
|
|
yield f'verify_blob_kzg_proof_case_invalid_blob_{(hash(bytes(identifier, "utf-8"))[:8]).hex()}', {
|
|
|
|
'input': {
|
|
|
|
'blob': encode_hex(blob),
|
|
|
|
'commitment': encode_hex(commitment),
|
|
|
|
'proof': encode_hex(proof),
|
|
|
|
},
|
|
|
|
'output': None
|
|
|
|
}
|
|
|
|
|
2023-05-02 15:57:49 +00:00
|
|
|
# Edge case: Invalid commitment
|
|
|
|
for commitment in INVALID_G1_POINTS:
|
|
|
|
blob = VALID_BLOBS[1]
|
|
|
|
proof = G1
|
|
|
|
expect_exception(spec.verify_blob_kzg_proof, blob, commitment, proof)
|
|
|
|
identifier = f'{encode_hex(hash(commitment))}'
|
|
|
|
yield f'verify_blob_kzg_proof_case_invalid_commitment_{(hash(bytes(identifier, "utf-8"))[:8]).hex()}', {
|
|
|
|
'input': {
|
|
|
|
'blob': encode_hex(blob),
|
|
|
|
'commitment': encode_hex(commitment),
|
|
|
|
'proof': encode_hex(proof),
|
|
|
|
},
|
|
|
|
'output': None
|
|
|
|
}
|
|
|
|
|
|
|
|
# Edge case: Invalid proof
|
|
|
|
for proof in INVALID_G1_POINTS:
|
|
|
|
blob = VALID_BLOBS[1]
|
|
|
|
commitment = G1
|
|
|
|
expect_exception(spec.verify_blob_kzg_proof, blob, commitment, proof)
|
|
|
|
identifier = f'{encode_hex(hash(proof))}'
|
|
|
|
yield f'verify_blob_kzg_proof_case_invalid_proof_{(hash(bytes(identifier, "utf-8"))[:8]).hex()}', {
|
|
|
|
'input': {
|
|
|
|
'blob': encode_hex(blob),
|
|
|
|
'commitment': encode_hex(commitment),
|
|
|
|
'proof': encode_hex(proof),
|
|
|
|
},
|
|
|
|
'output': None
|
|
|
|
}
|
|
|
|
|
2023-03-02 20:49:10 +00:00
|
|
|
|
2024-04-24 16:40:27 +00:00
|
|
|
###############################################################################
|
|
|
|
# Test cases for verify_blob_kzg_proof_batch
|
|
|
|
###############################################################################
|
|
|
|
|
2023-03-02 20:49:10 +00:00
|
|
|
def case06_verify_blob_kzg_proof_batch():
|
|
|
|
# Valid cases
|
|
|
|
proofs = []
|
|
|
|
commitments = []
|
|
|
|
for blob in VALID_BLOBS:
|
|
|
|
commitments.append(spec.blob_to_kzg_commitment(blob))
|
2023-03-07 17:50:56 +00:00
|
|
|
proofs.append(spec.compute_blob_kzg_proof(blob, commitments[-1]))
|
2023-03-02 20:49:10 +00:00
|
|
|
|
|
|
|
for i in range(len(proofs)):
|
|
|
|
assert spec.verify_blob_kzg_proof_batch(VALID_BLOBS[:i], commitments[:i], proofs[:i])
|
|
|
|
identifier = f'{encode_hex(hash(b"".join(VALID_BLOBS[:i])))}'
|
|
|
|
yield f'verify_blob_kzg_proof_batch_case_{(hash(bytes(identifier, "utf-8"))[:8]).hex()}', {
|
|
|
|
'input': {
|
|
|
|
'blobs': encode_hex_list(VALID_BLOBS[:i]),
|
|
|
|
'commitments': encode_hex_list(commitments[:i]),
|
|
|
|
'proofs': encode_hex_list(proofs[:i]),
|
|
|
|
},
|
|
|
|
'output': True
|
|
|
|
}
|
|
|
|
|
|
|
|
# Incorrect proof
|
|
|
|
proofs_incorrect = [bls_add_one(proofs[0])] + proofs[1:]
|
|
|
|
assert not spec.verify_blob_kzg_proof_batch(VALID_BLOBS, commitments, proofs_incorrect)
|
2023-09-19 15:09:38 +00:00
|
|
|
yield 'verify_blob_kzg_proof_batch_case_incorrect_proof_add_one', {
|
2023-03-02 20:49:10 +00:00
|
|
|
'input': {
|
|
|
|
'blobs': encode_hex_list(VALID_BLOBS),
|
|
|
|
'commitments': encode_hex_list(commitments),
|
|
|
|
'proofs': encode_hex_list(proofs_incorrect),
|
|
|
|
},
|
|
|
|
'output': False
|
|
|
|
}
|
|
|
|
|
2023-09-19 16:21:18 +00:00
|
|
|
# Incorrect `G1_POINT_AT_INFINITY` proof
|
|
|
|
blob = BLOB_RANDOM_VALID1
|
|
|
|
commitment = spec.blob_to_kzg_commitment(blob)
|
|
|
|
proof = spec.G1_POINT_AT_INFINITY
|
|
|
|
assert not spec.verify_blob_kzg_proof_batch([blob], [commitment], [proof])
|
|
|
|
yield 'verify_blob_kzg_proof_batch_case_incorrect_proof_point_at_infinity', {
|
|
|
|
'input': {
|
|
|
|
'blobs': encode_hex_list([blob]),
|
|
|
|
'commitments': encode_hex_list([commitment]),
|
|
|
|
'proofs': encode_hex_list([proof]),
|
|
|
|
},
|
|
|
|
'output': False
|
|
|
|
}
|
|
|
|
|
2023-03-07 21:56:55 +00:00
|
|
|
# Edge case: Invalid blobs
|
|
|
|
for blob in INVALID_BLOBS:
|
|
|
|
blobs_invalid = VALID_BLOBS[:4] + [blob] + VALID_BLOBS[5:]
|
|
|
|
expect_exception(spec.verify_blob_kzg_proof_batch, blobs_invalid, commitments, proofs)
|
|
|
|
identifier = f'{encode_hex(hash(blob))}'
|
|
|
|
yield f'verify_blob_kzg_proof_batch_case_invalid_blob_{(hash(bytes(identifier, "utf-8"))[:8]).hex()}', {
|
|
|
|
'input': {
|
|
|
|
'blobs': encode_hex_list(blobs_invalid),
|
|
|
|
'commitments': encode_hex_list(commitments),
|
|
|
|
'proofs': encode_hex_list(proofs),
|
|
|
|
},
|
|
|
|
'output': None
|
|
|
|
}
|
|
|
|
|
2023-05-02 15:57:49 +00:00
|
|
|
# Edge case: Invalid commitment
|
|
|
|
for commitment in INVALID_G1_POINTS:
|
|
|
|
blobs = VALID_BLOBS
|
|
|
|
commitments_invalid = [commitment] + commitments[1:]
|
|
|
|
expect_exception(spec.verify_blob_kzg_proof_batch, blobs, commitments_invalid, proofs)
|
|
|
|
identifier = f'{encode_hex(hash(commitment))}'
|
|
|
|
yield f'verify_blob_kzg_proof_batch_case_invalid_commitment_{(hash(bytes(identifier, "utf-8"))[:8]).hex()}', {
|
|
|
|
'input': {
|
|
|
|
'blobs': encode_hex_list(blobs),
|
|
|
|
'commitments': encode_hex_list(commitments_invalid),
|
|
|
|
'proofs': encode_hex_list(proofs),
|
|
|
|
},
|
|
|
|
'output': None
|
|
|
|
}
|
2023-03-07 21:56:55 +00:00
|
|
|
|
2023-05-02 15:57:49 +00:00
|
|
|
# Edge case: Invalid proof
|
|
|
|
for proof in INVALID_G1_POINTS:
|
|
|
|
blobs = VALID_BLOBS
|
|
|
|
proofs_invalid = [proof] + proofs[1:]
|
|
|
|
expect_exception(spec.verify_blob_kzg_proof_batch, blobs, commitments, proofs_invalid)
|
|
|
|
identifier = f'{encode_hex(hash(proof))}'
|
|
|
|
yield f'verify_blob_kzg_proof_batch_case_invalid_proof_{(hash(bytes(identifier, "utf-8"))[:8]).hex()}', {
|
|
|
|
'input': {
|
|
|
|
'blobs': encode_hex_list(blobs),
|
|
|
|
'commitments': encode_hex_list(commitments),
|
|
|
|
'proofs': encode_hex_list(proofs_invalid),
|
|
|
|
},
|
|
|
|
'output': None
|
|
|
|
}
|
2023-03-02 20:49:10 +00:00
|
|
|
|
|
|
|
# Edge case: Blob length different
|
|
|
|
expect_exception(spec.verify_blob_kzg_proof_batch, VALID_BLOBS[:-1], commitments, proofs)
|
|
|
|
yield 'verify_blob_kzg_proof_batch_case_blob_length_different', {
|
|
|
|
'input': {
|
|
|
|
'blobs': encode_hex_list(VALID_BLOBS[:-1]),
|
|
|
|
'commitments': encode_hex_list(commitments),
|
|
|
|
'proofs': encode_hex_list(proofs),
|
|
|
|
},
|
|
|
|
'output': None
|
|
|
|
}
|
|
|
|
|
|
|
|
# Edge case: Commitment length different
|
|
|
|
expect_exception(spec.verify_blob_kzg_proof_batch, VALID_BLOBS, commitments[:-1], proofs)
|
|
|
|
yield 'verify_blob_kzg_proof_batch_case_commitment_length_different', {
|
|
|
|
'input': {
|
|
|
|
'blobs': encode_hex_list(VALID_BLOBS),
|
|
|
|
'commitments': encode_hex_list(commitments[:-1]),
|
|
|
|
'proofs': encode_hex_list(proofs),
|
|
|
|
},
|
|
|
|
'output': None
|
|
|
|
}
|
|
|
|
|
|
|
|
# Edge case: Proof length different
|
|
|
|
expect_exception(spec.verify_blob_kzg_proof_batch, VALID_BLOBS, commitments, proofs[:-1])
|
|
|
|
yield 'verify_blob_kzg_proof_batch_case_proof_length_different', {
|
|
|
|
'input': {
|
|
|
|
'blobs': encode_hex_list(VALID_BLOBS),
|
|
|
|
'commitments': encode_hex_list(commitments),
|
|
|
|
'proofs': encode_hex_list(proofs[:-1]),
|
|
|
|
},
|
|
|
|
'output': None
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2024-04-24 16:40:27 +00:00
|
|
|
###############################################################################
|
|
|
|
# Main logic
|
|
|
|
###############################################################################
|
|
|
|
|
2023-03-02 20:49:10 +00:00
|
|
|
def create_provider(fork_name: SpecForkName,
|
|
|
|
handler_name: str,
|
|
|
|
test_case_fn: Callable[[], Iterable[Tuple[str, Dict[str, Any]]]]) -> gen_typing.TestProvider:
|
|
|
|
|
|
|
|
def prepare_fn() -> None:
|
|
|
|
# Nothing to load / change in spec. Maybe in future forks.
|
|
|
|
# Put the tests into the general config category, to not require any particular configuration.
|
|
|
|
return
|
|
|
|
|
|
|
|
def cases_fn() -> Iterable[gen_typing.TestCase]:
|
|
|
|
for data in test_case_fn():
|
|
|
|
(case_name, case_content) = data
|
|
|
|
yield gen_typing.TestCase(
|
|
|
|
fork_name=fork_name,
|
|
|
|
preset_name='general',
|
|
|
|
runner_name='kzg',
|
|
|
|
handler_name=handler_name,
|
2023-08-20 18:27:19 +00:00
|
|
|
suite_name='kzg-mainnet',
|
2023-03-02 20:49:10 +00:00
|
|
|
case_name=case_name,
|
|
|
|
case_fn=lambda: [('data', 'data', case_content)]
|
|
|
|
)
|
|
|
|
|
|
|
|
return gen_typing.TestProvider(prepare=prepare_fn, make_cases=cases_fn)
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
bls.use_arkworks()
|
|
|
|
gen_runner.run_generator("kzg", [
|
|
|
|
# DENEB
|
|
|
|
create_provider(DENEB, 'blob_to_kzg_commitment', case01_blob_to_kzg_commitment),
|
|
|
|
create_provider(DENEB, 'compute_kzg_proof', case02_compute_kzg_proof),
|
|
|
|
create_provider(DENEB, 'verify_kzg_proof', case03_verify_kzg_proof),
|
|
|
|
create_provider(DENEB, 'compute_blob_kzg_proof', case04_compute_blob_kzg_proof),
|
|
|
|
create_provider(DENEB, 'verify_blob_kzg_proof', case05_verify_blob_kzg_proof),
|
|
|
|
create_provider(DENEB, 'verify_blob_kzg_proof_batch', case06_verify_blob_kzg_proof_batch),
|
|
|
|
])
|