Add initial version of kzg_7594 test generator (#3693)
This commit is contained in:
parent
731caf8573
commit
f5277700e3
|
@ -0,0 +1,155 @@
|
|||
from hashlib import sha256
|
||||
|
||||
from eth_utils import (
|
||||
encode_hex,
|
||||
int_to_big_endian,
|
||||
)
|
||||
|
||||
from eth2spec.utils import bls
|
||||
from eth2spec.eip7594 import spec
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Helper functions
|
||||
###############################################################################
|
||||
|
||||
def expect_exception(func, *args):
|
||||
try:
|
||||
func(*args)
|
||||
except Exception:
|
||||
pass
|
||||
else:
|
||||
raise Exception("should have raised exception")
|
||||
|
||||
|
||||
def bls_add_one(x):
|
||||
"""
|
||||
Adds "one" (actually bls.G1()) to a compressed group element.
|
||||
Useful to compute definitely incorrect proofs.
|
||||
"""
|
||||
return bls.G1_to_bytes48(
|
||||
bls.add(bls.bytes48_to_G1(x), bls.G1())
|
||||
)
|
||||
|
||||
|
||||
def hash(x):
|
||||
return sha256(x).digest()
|
||||
|
||||
|
||||
def make_id(*args):
|
||||
values_str = "_".join(str(arg) for arg in args)
|
||||
return hash(bytes(values_str, "utf-8"))[:8].hex()
|
||||
|
||||
|
||||
def field_element_bytes(x):
|
||||
return int.to_bytes(x % spec.BLS_MODULUS, 32, spec.KZG_ENDIANNESS)
|
||||
|
||||
|
||||
def field_element_bytes_unchecked(x):
|
||||
return int.to_bytes(x, 32, spec.KZG_ENDIANNESS)
|
||||
|
||||
|
||||
def encode_hex_list(a):
|
||||
return [encode_hex(x) for x in a]
|
||||
|
||||
|
||||
def int_to_hex(n: int, byte_length: int = None) -> str:
|
||||
byte_value = int_to_big_endian(n)
|
||||
if byte_length:
|
||||
byte_value = byte_value.rjust(byte_length, b'\x00')
|
||||
return encode_hex(byte_value)
|
||||
|
||||
|
||||
def evaluate_blob_at(blob, z):
|
||||
return field_element_bytes(
|
||||
spec.evaluate_polynomial_in_evaluation_form(spec.blob_to_polynomial(blob), spec.bytes_to_bls_field(z))
|
||||
)
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Global variables
|
||||
###############################################################################
|
||||
|
||||
BLS_MODULUS_BYTES = spec.BLS_MODULUS.to_bytes(32, spec.KZG_ENDIANNESS)
|
||||
|
||||
# Field Elements
|
||||
|
||||
FE_VALID1 = field_element_bytes(0)
|
||||
FE_VALID2 = field_element_bytes(1)
|
||||
FE_VALID3 = field_element_bytes(2)
|
||||
FE_VALID4 = field_element_bytes(pow(5, 1235, spec.BLS_MODULUS))
|
||||
FE_VALID5 = field_element_bytes(spec.BLS_MODULUS - 1)
|
||||
FE_VALID6 = field_element_bytes(spec.compute_roots_of_unity(spec.FIELD_ELEMENTS_PER_BLOB)[1])
|
||||
VALID_FIELD_ELEMENTS = [FE_VALID1, FE_VALID2, FE_VALID3, FE_VALID4, FE_VALID5, FE_VALID6]
|
||||
|
||||
FE_INVALID_EQUAL_TO_MODULUS = field_element_bytes_unchecked(spec.BLS_MODULUS)
|
||||
FE_INVALID_MODULUS_PLUS_ONE = field_element_bytes_unchecked(spec.BLS_MODULUS + 1)
|
||||
FE_INVALID_UINT256_MAX = field_element_bytes_unchecked(2**256 - 1)
|
||||
FE_INVALID_UINT256_MID = field_element_bytes_unchecked(2**256 - 2**128)
|
||||
FE_INVALID_LENGTH_PLUS_ONE = VALID_FIELD_ELEMENTS[0] + b"\x00"
|
||||
FE_INVALID_LENGTH_MINUS_ONE = VALID_FIELD_ELEMENTS[0][:-1]
|
||||
INVALID_FIELD_ELEMENTS = [FE_INVALID_EQUAL_TO_MODULUS, FE_INVALID_MODULUS_PLUS_ONE,
|
||||
FE_INVALID_UINT256_MAX, FE_INVALID_UINT256_MID,
|
||||
FE_INVALID_LENGTH_PLUS_ONE, FE_INVALID_LENGTH_MINUS_ONE]
|
||||
|
||||
# Blobs
|
||||
|
||||
BLOB_ALL_ZEROS = spec.Blob()
|
||||
BLOB_ALL_TWOS = spec.Blob(b''.join([field_element_bytes(2) for n in range(4096)]))
|
||||
BLOB_RANDOM_VALID1 = spec.Blob(b''.join([field_element_bytes(pow(2, n + 256, spec.BLS_MODULUS)) for n in range(4096)]))
|
||||
BLOB_RANDOM_VALID2 = spec.Blob(b''.join([field_element_bytes(pow(3, n + 256, spec.BLS_MODULUS)) for n in range(4096)]))
|
||||
BLOB_RANDOM_VALID3 = spec.Blob(b''.join([field_element_bytes(pow(5, n + 256, spec.BLS_MODULUS)) for n in range(4096)]))
|
||||
BLOB_ALL_MODULUS_MINUS_ONE = spec.Blob(b''.join([field_element_bytes(spec.BLS_MODULUS - 1) for n in range(4096)]))
|
||||
BLOB_ALMOST_ZERO = spec.Blob(b''.join([field_element_bytes(1 if n == 3211 else 0) for n in range(4096)]))
|
||||
|
||||
BLOB_INVALID = spec.Blob(b'\xFF' * 4096 * 32)
|
||||
BLOB_INVALID_CLOSE = spec.Blob(b''.join(
|
||||
[BLS_MODULUS_BYTES if n == 2111 else field_element_bytes(0) for n in range(4096)]
|
||||
))
|
||||
BLOB_INVALID_LENGTH_PLUS_ONE = BLOB_RANDOM_VALID1 + b"\x00"
|
||||
BLOB_INVALID_LENGTH_MINUS_ONE = BLOB_RANDOM_VALID1[:-1]
|
||||
|
||||
VALID_BLOBS = [BLOB_ALL_ZEROS, BLOB_ALL_TWOS, BLOB_RANDOM_VALID1, BLOB_RANDOM_VALID2,
|
||||
BLOB_RANDOM_VALID3, BLOB_ALL_MODULUS_MINUS_ONE, BLOB_ALMOST_ZERO]
|
||||
INVALID_BLOBS = [BLOB_INVALID, BLOB_INVALID_CLOSE, BLOB_INVALID_LENGTH_PLUS_ONE, BLOB_INVALID_LENGTH_MINUS_ONE]
|
||||
|
||||
# Commitments
|
||||
|
||||
VALID_COMMITMENTS = [spec.blob_to_kzg_commitment(blob) for blob in VALID_BLOBS]
|
||||
|
||||
# Points
|
||||
|
||||
G1 = bls.G1_to_bytes48(bls.G1())
|
||||
G1_INVALID_TOO_FEW_BYTES = G1[:-1]
|
||||
G1_INVALID_TOO_MANY_BYTES = G1 + b"\x00"
|
||||
G1_INVALID_P1_NOT_IN_G1 = bytes.fromhex("8123456789abcdef0123456789abcdef0123456789abcdef" +
|
||||
"0123456789abcdef0123456789abcdef0123456789abcdef")
|
||||
G1_INVALID_P1_NOT_ON_CURVE = bytes.fromhex("8123456789abcdef0123456789abcdef0123456789abcdef" +
|
||||
"0123456789abcdef0123456789abcdef0123456789abcde0")
|
||||
INVALID_G1_POINTS = [G1_INVALID_TOO_FEW_BYTES, G1_INVALID_TOO_MANY_BYTES,
|
||||
G1_INVALID_P1_NOT_IN_G1, G1_INVALID_P1_NOT_ON_CURVE]
|
||||
|
||||
# Individual Cells
|
||||
|
||||
CELL_RANDOM_VALID1 = b"".join([field_element_bytes(pow(2, n + 256, spec.BLS_MODULUS))
|
||||
for n in range(spec.FIELD_ELEMENTS_PER_CELL)])
|
||||
CELL_RANDOM_VALID2 = b"".join([field_element_bytes(pow(3, n + 256, spec.BLS_MODULUS))
|
||||
for n in range(spec.FIELD_ELEMENTS_PER_CELL)])
|
||||
CELL_RANDOM_VALID3 = b"".join([field_element_bytes(pow(5, n + 256, spec.BLS_MODULUS))
|
||||
for n in range(spec.FIELD_ELEMENTS_PER_CELL)])
|
||||
|
||||
CELL_ALL_MAX_VALUE = b"".join([field_element_bytes_unchecked(2 ** 256 - 1)
|
||||
for n in range(spec.FIELD_ELEMENTS_PER_CELL)])
|
||||
CELL_ONE_INVALID_FIELD = b"".join([field_element_bytes_unchecked(spec.BLS_MODULUS)
|
||||
if n == 7 else field_element_bytes(0)
|
||||
for n in range(spec.FIELD_ELEMENTS_PER_CELL)])
|
||||
CELL_INVALID_TOO_FEW_BYTES = CELL_RANDOM_VALID1[:-1]
|
||||
CELL_INVALID_TOO_MANY_BYTES = CELL_RANDOM_VALID2 + b"\x00"
|
||||
|
||||
VALID_INDIVIDUAL_RANDOM_CELL_BYTES = [CELL_RANDOM_VALID1, CELL_RANDOM_VALID2, CELL_RANDOM_VALID3]
|
||||
INVALID_INDIVIDUAL_CELL_BYTES = [CELL_ALL_MAX_VALUE, CELL_ONE_INVALID_FIELD, CELL_INVALID_TOO_FEW_BYTES,
|
||||
CELL_INVALID_TOO_MANY_BYTES]
|
||||
|
||||
# Cells & Proofs
|
||||
|
||||
VALID_CELLS_AND_PROOFS = [] # Saved in case02_compute_cells_and_proofs
|
|
@ -1,118 +1,37 @@
|
|||
"""
|
||||
KZG 4844 test vectors generator
|
||||
KZG test vectors generator for EIP-4844
|
||||
"""
|
||||
|
||||
from hashlib import sha256
|
||||
from typing import Tuple, Iterable, Any, Callable, Dict
|
||||
|
||||
from eth_utils import (
|
||||
encode_hex,
|
||||
int_to_big_endian,
|
||||
)
|
||||
from eth_utils import encode_hex
|
||||
|
||||
from eth2spec.utils import bls
|
||||
from eth2spec.deneb import spec
|
||||
from eth2spec.gen_helpers.gen_base import gen_runner, gen_typing
|
||||
from eth2spec.test.helpers.constants import DENEB
|
||||
from eth2spec.test.helpers.typing import SpecForkName
|
||||
from eth2spec.gen_helpers.gen_base import gen_runner, gen_typing
|
||||
from eth2spec.deneb import spec
|
||||
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
|
||||
|
||||
|
||||
def expect_exception(func, *args):
|
||||
try:
|
||||
func(*args)
|
||||
except Exception:
|
||||
pass
|
||||
else:
|
||||
raise Exception("should have raised exception")
|
||||
|
||||
|
||||
def field_element_bytes(x):
|
||||
return int.to_bytes(x % spec.BLS_MODULUS, 32, spec.KZG_ENDIANNESS)
|
||||
|
||||
|
||||
def field_element_bytes_unchecked(x):
|
||||
return int.to_bytes(x, 32, spec.KZG_ENDIANNESS)
|
||||
|
||||
|
||||
def encode_hex_list(a):
|
||||
return [encode_hex(x) for x in a]
|
||||
|
||||
|
||||
def bls_add_one(x):
|
||||
"""
|
||||
Adds "one" (actually bls.G1()) to a compressed group element.
|
||||
Useful to compute definitely incorrect proofs.
|
||||
"""
|
||||
return bls.G1_to_bytes48(
|
||||
bls.add(bls.bytes48_to_G1(x), bls.G1())
|
||||
)
|
||||
|
||||
|
||||
def evaluate_blob_at(blob, z):
|
||||
return field_element_bytes(
|
||||
spec.evaluate_polynomial_in_evaluation_form(spec.blob_to_polynomial(blob), spec.bytes_to_bls_field(z))
|
||||
)
|
||||
|
||||
|
||||
BLS_MODULUS_BYTES = spec.BLS_MODULUS.to_bytes(32, spec.KZG_ENDIANNESS)
|
||||
|
||||
G1 = bls.G1_to_bytes48(bls.G1())
|
||||
G1_INVALID_TOO_FEW_BYTES = G1[:-1]
|
||||
G1_INVALID_TOO_MANY_BYTES = G1 + b"\x00"
|
||||
G1_INVALID_P1_NOT_IN_G1 = bytes.fromhex("8123456789abcdef0123456789abcdef0123456789abcdef" +
|
||||
"0123456789abcdef0123456789abcdef0123456789abcdef")
|
||||
G1_INVALID_P1_NOT_ON_CURVE = bytes.fromhex("8123456789abcdef0123456789abcdef0123456789abcdef" +
|
||||
"0123456789abcdef0123456789abcdef0123456789abcde0")
|
||||
INVALID_G1_POINTS = [G1_INVALID_TOO_FEW_BYTES, G1_INVALID_TOO_MANY_BYTES,
|
||||
G1_INVALID_P1_NOT_IN_G1, G1_INVALID_P1_NOT_ON_CURVE]
|
||||
|
||||
BLOB_ALL_ZEROS = spec.Blob()
|
||||
BLOB_ALL_TWOS = spec.Blob(b''.join([field_element_bytes(2) for n in range(4096)]))
|
||||
BLOB_RANDOM_VALID1 = spec.Blob(b''.join([field_element_bytes(pow(2, n + 256, spec.BLS_MODULUS)) for n in range(4096)]))
|
||||
BLOB_RANDOM_VALID2 = spec.Blob(b''.join([field_element_bytes(pow(3, n + 256, spec.BLS_MODULUS)) for n in range(4096)]))
|
||||
BLOB_RANDOM_VALID3 = spec.Blob(b''.join([field_element_bytes(pow(5, n + 256, spec.BLS_MODULUS)) for n in range(4096)]))
|
||||
BLOB_ALL_MODULUS_MINUS_ONE = spec.Blob(b''.join([field_element_bytes(spec.BLS_MODULUS - 1) for n in range(4096)]))
|
||||
BLOB_ALMOST_ZERO = spec.Blob(b''.join([field_element_bytes(1 if n == 3211 else 0) for n in range(4096)]))
|
||||
BLOB_INVALID = spec.Blob(b'\xFF' * 4096 * 32)
|
||||
BLOB_INVALID_CLOSE = spec.Blob(b''.join(
|
||||
[BLS_MODULUS_BYTES if n == 2111 else field_element_bytes(0) for n in range(4096)]
|
||||
))
|
||||
BLOB_INVALID_LENGTH_PLUS_ONE = BLOB_RANDOM_VALID1 + b"\x00"
|
||||
BLOB_INVALID_LENGTH_MINUS_ONE = BLOB_RANDOM_VALID1[:-1]
|
||||
|
||||
VALID_BLOBS = [BLOB_ALL_ZEROS, BLOB_ALL_TWOS, BLOB_RANDOM_VALID1, BLOB_RANDOM_VALID2,
|
||||
BLOB_RANDOM_VALID3, BLOB_ALL_MODULUS_MINUS_ONE, BLOB_ALMOST_ZERO]
|
||||
INVALID_BLOBS = [BLOB_INVALID, BLOB_INVALID_CLOSE, BLOB_INVALID_LENGTH_PLUS_ONE, BLOB_INVALID_LENGTH_MINUS_ONE]
|
||||
|
||||
FE_VALID1 = field_element_bytes(0)
|
||||
FE_VALID2 = field_element_bytes(1)
|
||||
FE_VALID3 = field_element_bytes(2)
|
||||
FE_VALID4 = field_element_bytes(pow(5, 1235, spec.BLS_MODULUS))
|
||||
FE_VALID5 = field_element_bytes(spec.BLS_MODULUS - 1)
|
||||
FE_VALID6 = field_element_bytes(spec.compute_roots_of_unity(spec.FIELD_ELEMENTS_PER_BLOB)[1])
|
||||
VALID_FIELD_ELEMENTS = [FE_VALID1, FE_VALID2, FE_VALID3, FE_VALID4, FE_VALID5, FE_VALID6]
|
||||
|
||||
FE_INVALID_EQUAL_TO_MODULUS = field_element_bytes_unchecked(spec.BLS_MODULUS)
|
||||
FE_INVALID_MODULUS_PLUS_ONE = field_element_bytes_unchecked(spec.BLS_MODULUS + 1)
|
||||
FE_INVALID_UINT256_MAX = field_element_bytes_unchecked(2**256 - 1)
|
||||
FE_INVALID_UINT256_MID = field_element_bytes_unchecked(2**256 - 2**128)
|
||||
FE_INVALID_LENGTH_PLUS_ONE = VALID_FIELD_ELEMENTS[0] + b"\x00"
|
||||
FE_INVALID_LENGTH_MINUS_ONE = VALID_FIELD_ELEMENTS[0][:-1]
|
||||
INVALID_FIELD_ELEMENTS = [FE_INVALID_EQUAL_TO_MODULUS, FE_INVALID_MODULUS_PLUS_ONE,
|
||||
FE_INVALID_UINT256_MAX, FE_INVALID_UINT256_MID,
|
||||
FE_INVALID_LENGTH_PLUS_ONE, FE_INVALID_LENGTH_MINUS_ONE]
|
||||
|
||||
|
||||
def hash(x):
|
||||
return sha256(x).digest()
|
||||
|
||||
|
||||
def int_to_hex(n: int, byte_length: int = None) -> str:
|
||||
byte_value = int_to_big_endian(n)
|
||||
if byte_length:
|
||||
byte_value = byte_value.rjust(byte_length, b'\x00')
|
||||
return encode_hex(byte_value)
|
||||
|
||||
###############################################################################
|
||||
# Test cases for blob_to_kzg_commitment
|
||||
###############################################################################
|
||||
|
||||
def case01_blob_to_kzg_commitment():
|
||||
# Valid cases
|
||||
|
@ -138,6 +57,10 @@ def case01_blob_to_kzg_commitment():
|
|||
}
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Test cases for compute_kzg_proof
|
||||
###############################################################################
|
||||
|
||||
def case02_compute_kzg_proof():
|
||||
# Valid cases
|
||||
for blob in VALID_BLOBS:
|
||||
|
@ -179,6 +102,10 @@ def case02_compute_kzg_proof():
|
|||
}
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Test cases for verify_kzg_proof
|
||||
###############################################################################
|
||||
|
||||
def case03_verify_kzg_proof():
|
||||
# Valid cases
|
||||
for blob in VALID_BLOBS:
|
||||
|
@ -341,6 +268,10 @@ def case03_verify_kzg_proof():
|
|||
}
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Test cases for compute_blob_kzg_proof
|
||||
###############################################################################
|
||||
|
||||
def case04_compute_blob_kzg_proof():
|
||||
# Valid cases
|
||||
for blob in VALID_BLOBS:
|
||||
|
@ -382,6 +313,10 @@ def case04_compute_blob_kzg_proof():
|
|||
}
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Test cases for verify_blob_kzg_proof
|
||||
###############################################################################
|
||||
|
||||
def case05_verify_blob_kzg_proof():
|
||||
# Valid cases
|
||||
for blob in VALID_BLOBS:
|
||||
|
@ -503,6 +438,10 @@ def case05_verify_blob_kzg_proof():
|
|||
}
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Test cases for verify_blob_kzg_proof_batch
|
||||
###############################################################################
|
||||
|
||||
def case06_verify_blob_kzg_proof_batch():
|
||||
# Valid cases
|
||||
proofs = []
|
||||
|
@ -627,6 +566,10 @@ def case06_verify_blob_kzg_proof_batch():
|
|||
}
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Main logic
|
||||
###############################################################################
|
||||
|
||||
def create_provider(fork_name: SpecForkName,
|
||||
handler_name: str,
|
||||
test_case_fn: Callable[[], Iterable[Tuple[str, Dict[str, Any]]]]) -> gen_typing.TestProvider:
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
# KZG Test Generator for EIP-7594
|
||||
|
||||
These tests are specific to the API required for implementing PeerDAS polynomial commitment sampling.
|
|
@ -0,0 +1,837 @@
|
|||
"""
|
||||
KZG test vectors generator for EIP-7594
|
||||
"""
|
||||
|
||||
from typing import Tuple, Iterable, Any, Callable, Dict
|
||||
|
||||
from eth_utils import encode_hex
|
||||
|
||||
from eth2spec.eip7594 import spec
|
||||
from eth2spec.gen_helpers.gen_base import gen_runner, gen_typing
|
||||
from eth2spec.test.helpers.constants import EIP7594
|
||||
from eth2spec.test.helpers.typing import SpecForkName
|
||||
from eth2spec.test.utils.kzg_tests import (
|
||||
BLOB_RANDOM_VALID1,
|
||||
BLOB_RANDOM_VALID2,
|
||||
BLOB_RANDOM_VALID3,
|
||||
CELL_RANDOM_VALID1,
|
||||
CELL_RANDOM_VALID2,
|
||||
INVALID_BLOBS,
|
||||
INVALID_G1_POINTS,
|
||||
INVALID_INDIVIDUAL_CELL_BYTES,
|
||||
VALID_BLOBS,
|
||||
VALID_CELLS_AND_PROOFS,
|
||||
VALID_COMMITMENTS,
|
||||
VALID_INDIVIDUAL_RANDOM_CELL_BYTES,
|
||||
bls_add_one,
|
||||
encode_hex_list,
|
||||
expect_exception,
|
||||
make_id,
|
||||
)
|
||||
from eth2spec.utils import bls
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Test cases for compute_cells
|
||||
###############################################################################
|
||||
|
||||
def case01_compute_cells():
|
||||
# Valid cases
|
||||
for blob in VALID_BLOBS:
|
||||
cells = spec.compute_cells(blob)
|
||||
identifier = make_id(blob)
|
||||
yield f'compute_cells_case_valid_{identifier}', {
|
||||
'input': {
|
||||
'blob': encode_hex(blob),
|
||||
},
|
||||
'output': encode_hex_list(cells)
|
||||
}
|
||||
|
||||
# Edge case: Invalid blobs
|
||||
for blob in INVALID_BLOBS:
|
||||
expect_exception(spec.compute_cells, blob)
|
||||
identifier = make_id(blob)
|
||||
yield f'compute_cells_case_invalid_blob_{identifier}', {
|
||||
'input': {
|
||||
'blob': encode_hex(blob)
|
||||
},
|
||||
'output': None
|
||||
}
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Test cases for compute_cells_and_proofs
|
||||
###############################################################################
|
||||
|
||||
def case02_compute_cells_and_proofs():
|
||||
# Valid cases
|
||||
for blob in VALID_BLOBS:
|
||||
cells, proofs = spec.compute_cells_and_proofs(blob)
|
||||
# Save cells & proofs here to save on time.
|
||||
VALID_CELLS_AND_PROOFS.append((cells, proofs))
|
||||
identifier = make_id(blob)
|
||||
yield f'compute_cells_and_proofs_case_valid_{identifier}', {
|
||||
'input': {
|
||||
'blob': encode_hex(blob),
|
||||
},
|
||||
'output': (encode_hex_list(cells), encode_hex_list(proofs))
|
||||
}
|
||||
|
||||
# Edge case: Invalid blobs
|
||||
for blob in INVALID_BLOBS:
|
||||
expect_exception(spec.compute_cells_and_proofs, blob)
|
||||
identifier = make_id(blob)
|
||||
yield f'compute_cells_and_proofs_case_invalid_blob_{identifier}', {
|
||||
'input': {
|
||||
'blob': encode_hex(blob)
|
||||
},
|
||||
'output': None
|
||||
}
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Test cases for verify_cell_proof
|
||||
###############################################################################
|
||||
|
||||
def case03_verify_cell_proof():
|
||||
# Valid cases
|
||||
for i in range(len(VALID_BLOBS)):
|
||||
cells, proofs = VALID_CELLS_AND_PROOFS[i]
|
||||
commitment = VALID_COMMITMENTS[i]
|
||||
cell_id = (2 ** i - 1) % spec.CELLS_PER_EXT_BLOB
|
||||
cell = cells[cell_id]
|
||||
proof = proofs[cell_id]
|
||||
assert spec.verify_cell_proof(commitment, cell_id, cell, proof)
|
||||
identifier = make_id(commitment, cell_id, cell, proof)
|
||||
yield f'verify_cell_proof_case_valid_{identifier}', {
|
||||
'input': {
|
||||
'commitment': encode_hex(commitment),
|
||||
'cell_id': cell_id,
|
||||
'cell': encode_hex(cell),
|
||||
'proof': encode_hex(proof),
|
||||
},
|
||||
'output': True
|
||||
}
|
||||
|
||||
# Incorrect commitment
|
||||
for i in range(len(VALID_BLOBS)):
|
||||
cells, proofs = VALID_CELLS_AND_PROOFS[i]
|
||||
commitment = bls_add_one(VALID_COMMITMENTS[i])
|
||||
cell_id = 99 % spec.CELLS_PER_EXT_BLOB
|
||||
cell = cells[cell_id]
|
||||
proof = proofs[cell_id]
|
||||
assert not spec.verify_cell_proof(commitment, cell_id, cell, proof)
|
||||
identifier = make_id(commitment, cell_id, cell, proof)
|
||||
yield f'verify_cell_proof_case_incorrect_commitment_{identifier}', {
|
||||
'input': {
|
||||
'commitment': encode_hex(commitment),
|
||||
'cell_id': cell_id,
|
||||
'cell': encode_hex(cell),
|
||||
'proof': encode_hex(proof),
|
||||
},
|
||||
'output': False
|
||||
}
|
||||
|
||||
# Incorrect cell
|
||||
for i in range(len(VALID_INDIVIDUAL_RANDOM_CELL_BYTES)):
|
||||
cell_id = 16 % spec.CELLS_PER_EXT_BLOB
|
||||
commitment = VALID_COMMITMENTS[i]
|
||||
cells, proofs = VALID_CELLS_AND_PROOFS[i]
|
||||
cell = VALID_INDIVIDUAL_RANDOM_CELL_BYTES[i]
|
||||
proof = proofs[cell_id]
|
||||
assert not spec.verify_cell_proof(commitment, cell_id, cell, proof)
|
||||
identifier = make_id(commitment, cell_id, cell, proof)
|
||||
yield f'verify_cell_proof_case_incorrect_cell_{identifier}', {
|
||||
'input': {
|
||||
'commitment': encode_hex(commitment),
|
||||
'cell_id': cell_id,
|
||||
'cell': encode_hex(cell),
|
||||
'proof': encode_hex(proof),
|
||||
},
|
||||
'output': False
|
||||
}
|
||||
|
||||
# Incorrect proof
|
||||
for i in range(len(VALID_BLOBS)):
|
||||
cell_id = 91 % spec.CELLS_PER_EXT_BLOB
|
||||
commitment = VALID_COMMITMENTS[i]
|
||||
cells, proofs = VALID_CELLS_AND_PROOFS[i]
|
||||
cell = cells[cell_id]
|
||||
proof = bls_add_one(proofs[cell_id])
|
||||
assert not spec.verify_cell_proof(commitment, cell_id, cell, proof)
|
||||
identifier = make_id(commitment, cell_id, cell, proof)
|
||||
yield f'verify_cell_proof_case_incorrect_proof_{identifier}', {
|
||||
'input': {
|
||||
'commitment': encode_hex(commitment),
|
||||
'cell_id': cell_id,
|
||||
'cell': encode_hex(cell),
|
||||
'proof': encode_hex(proof),
|
||||
},
|
||||
'output': False
|
||||
}
|
||||
|
||||
# Edge case: Invalid commitment
|
||||
for commitment in INVALID_G1_POINTS:
|
||||
cells, proofs = VALID_CELLS_AND_PROOFS[0]
|
||||
cell_id = 81 % spec.CELLS_PER_EXT_BLOB
|
||||
cell = cells[cell_id]
|
||||
proof = proofs[cell_id]
|
||||
expect_exception(spec.verify_cell_proof, commitment, cell_id, cell, proof)
|
||||
identifier = make_id(commitment, cell_id, cell, proof)
|
||||
yield f'verify_cell_proof_case_invalid_commitment_{identifier}', {
|
||||
'input': {
|
||||
'commitment': encode_hex(commitment),
|
||||
'cell_id': cell_id,
|
||||
'cell': encode_hex(cell),
|
||||
'proof': encode_hex(proof),
|
||||
},
|
||||
'output': None
|
||||
}
|
||||
|
||||
# Edge case: Invalid cell_id
|
||||
for cell_id in [spec.CELLS_PER_EXT_BLOB, spec.CELLS_PER_EXT_BLOB + 1]:
|
||||
cells, proofs = VALID_CELLS_AND_PROOFS[1]
|
||||
commitment = VALID_COMMITMENTS[1]
|
||||
cell = cells[0]
|
||||
proof = proofs[0]
|
||||
expect_exception(spec.verify_cell_proof, commitment, cell_id, cell, proof)
|
||||
identifier = make_id(commitment, cell_id, cell, proof)
|
||||
yield f'verify_cell_proof_case_invalid_cell_id_{identifier}', {
|
||||
'input': {
|
||||
'commitment': encode_hex(commitment),
|
||||
'cell_id': cell_id,
|
||||
'cell': encode_hex(cell),
|
||||
'proof': encode_hex(proof),
|
||||
},
|
||||
'output': None
|
||||
}
|
||||
|
||||
# Edge case: Invalid cell
|
||||
for cell in INVALID_INDIVIDUAL_CELL_BYTES:
|
||||
cell_id = 32 % spec.CELLS_PER_EXT_BLOB
|
||||
commitment = VALID_COMMITMENTS[2]
|
||||
cells, proofs = VALID_CELLS_AND_PROOFS[2]
|
||||
proof = proofs[cell_id]
|
||||
expect_exception(spec.verify_cell_proof, commitment, cell_id, cell, proof)
|
||||
identifier = make_id(commitment, cell_id, cell, proof)
|
||||
yield f'verify_cell_proof_case_invalid_cell_{identifier}', {
|
||||
'input': {
|
||||
'commitment': encode_hex(commitment),
|
||||
'cell_id': cell_id,
|
||||
'cell': encode_hex(cell),
|
||||
'proof': encode_hex(proof),
|
||||
},
|
||||
'output': None
|
||||
}
|
||||
|
||||
# Edge case: Invalid proof
|
||||
for proof in INVALID_G1_POINTS:
|
||||
cells, _ = VALID_CELLS_AND_PROOFS[3]
|
||||
commitment = VALID_COMMITMENTS[3]
|
||||
cell_id = 36 % spec.CELLS_PER_EXT_BLOB
|
||||
cell = cells[cell_id]
|
||||
expect_exception(spec.verify_cell_proof, commitment, cell_id, cell, proof)
|
||||
identifier = make_id(commitment, cell_id, cell, proof)
|
||||
yield f'verify_cell_proof_case_invalid_proof_{identifier}', {
|
||||
'input': {
|
||||
'commitment': encode_hex(commitment),
|
||||
'cell_id': cell_id,
|
||||
'cell': encode_hex(cell),
|
||||
'proof': encode_hex(proof),
|
||||
},
|
||||
'output': None
|
||||
}
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Test cases for verify_cell_proof_batch
|
||||
###############################################################################
|
||||
|
||||
def case04_verify_cell_proof_batch():
|
||||
# Valid cases
|
||||
for i in range(len(VALID_BLOBS)):
|
||||
cells, proofs = VALID_CELLS_AND_PROOFS[i]
|
||||
row_commitments = [VALID_COMMITMENTS[i]]
|
||||
row_indices = [0] * spec.CELLS_PER_EXT_BLOB
|
||||
column_indices = list(range(spec.CELLS_PER_EXT_BLOB))
|
||||
assert spec.verify_cell_proof_batch(row_commitments, row_indices, column_indices, cells, proofs)
|
||||
identifier = make_id(row_commitments, row_indices, column_indices, cells, proofs)
|
||||
yield f'verify_cell_proof_batch_case_valid_{identifier}', {
|
||||
'input': {
|
||||
'row_commitments': encode_hex_list(row_commitments),
|
||||
'row_indices': row_indices,
|
||||
'column_indices': column_indices,
|
||||
'cells': encode_hex_list(cells),
|
||||
'proofs': encode_hex_list(proofs),
|
||||
},
|
||||
'output': True
|
||||
}
|
||||
|
||||
# Valid: zero cells
|
||||
cells, row_commitments, row_indices, column_indices, proofs = [], [], [], [], []
|
||||
assert spec.verify_cell_proof_batch(row_commitments, row_indices, column_indices, cells, proofs)
|
||||
identifier = make_id(row_commitments, row_indices, column_indices, cells, proofs)
|
||||
yield f'verify_cell_proof_batch_case_valid_zero_cells_{identifier}', {
|
||||
'input': {
|
||||
'row_commitments': encode_hex_list(row_commitments),
|
||||
'row_indices': row_indices,
|
||||
'column_indices': column_indices,
|
||||
'cells': encode_hex_list(cells),
|
||||
'proofs': encode_hex_list(proofs),
|
||||
},
|
||||
'output': True
|
||||
}
|
||||
|
||||
# Valid: Verify cells from multiple blobs
|
||||
cells0, proofs0 = VALID_CELLS_AND_PROOFS[0]
|
||||
cells1, proofs1 = VALID_CELLS_AND_PROOFS[1]
|
||||
row_commitments = VALID_COMMITMENTS[:2]
|
||||
row_indices = [0, 1]
|
||||
column_indices = [0, 0]
|
||||
cells = [cells0[0], cells1[0]]
|
||||
proofs = [proofs0[0], proofs1[0]]
|
||||
assert spec.verify_cell_proof_batch(row_commitments, row_indices, column_indices, cells, proofs)
|
||||
identifier = make_id(row_commitments, row_indices, column_indices, cells, proofs)
|
||||
yield f'verify_cell_proof_batch_case_valid_multiple_blobs_{identifier}', {
|
||||
'input': {
|
||||
'row_commitments': encode_hex_list(row_commitments),
|
||||
'row_indices': row_indices,
|
||||
'column_indices': column_indices,
|
||||
'cells': encode_hex_list(cells),
|
||||
'proofs': encode_hex_list(proofs),
|
||||
},
|
||||
'output': True
|
||||
}
|
||||
|
||||
# Valid: Unused row commitments
|
||||
cells, proofs = VALID_CELLS_AND_PROOFS[2]
|
||||
cells, proofs = cells[:3], proofs[:3]
|
||||
# Provide list of all commitments
|
||||
row_commitments = VALID_COMMITMENTS
|
||||
row_indices = [2] * len(cells)
|
||||
column_indices = list(range(len(cells)))
|
||||
assert spec.verify_cell_proof_batch(row_commitments, row_indices, column_indices, cells, proofs)
|
||||
identifier = make_id(row_commitments, row_indices, column_indices, cells, proofs)
|
||||
yield f'verify_cell_proof_batch_case_valid_unused_row_commitments_{identifier}', {
|
||||
'input': {
|
||||
'row_commitments': encode_hex_list(row_commitments),
|
||||
'row_indices': row_indices,
|
||||
'column_indices': column_indices,
|
||||
'cells': encode_hex_list(cells),
|
||||
'proofs': encode_hex_list(proofs),
|
||||
},
|
||||
'output': True
|
||||
}
|
||||
|
||||
# Valid: Same cell multiple times
|
||||
row_commitments = [VALID_COMMITMENTS[3]]
|
||||
num_duplicates = 3
|
||||
row_indices = [0] * num_duplicates
|
||||
column_indices = [0] * num_duplicates
|
||||
cells = [VALID_CELLS_AND_PROOFS[3][0][0]] * num_duplicates
|
||||
proofs = [VALID_CELLS_AND_PROOFS[3][1][0]] * num_duplicates
|
||||
assert spec.verify_cell_proof_batch(row_commitments, row_indices, column_indices, cells, proofs)
|
||||
identifier = make_id(row_commitments, row_indices, column_indices, cells, proofs)
|
||||
yield f'verify_cell_proof_batch_case_valid_same_cell_multiple_times_{identifier}', {
|
||||
'input': {
|
||||
'row_commitments': encode_hex_list(row_commitments),
|
||||
'row_indices': row_indices,
|
||||
'column_indices': column_indices,
|
||||
'cells': encode_hex_list(cells),
|
||||
'proofs': encode_hex_list(proofs),
|
||||
},
|
||||
'output': True
|
||||
}
|
||||
|
||||
# Incorrect row commitment
|
||||
cells, proofs = VALID_CELLS_AND_PROOFS[5]
|
||||
cells, proofs = cells[:1], proofs[:1]
|
||||
# Change commitment so it's wrong
|
||||
row_commitments = [bls_add_one(VALID_COMMITMENTS[5])]
|
||||
row_indices = [0] * len(cells)
|
||||
column_indices = list(range(len(cells)))
|
||||
assert not spec.verify_cell_proof_batch(row_commitments, row_indices, column_indices, cells, proofs)
|
||||
identifier = make_id(row_commitments, row_indices, column_indices, cells, proofs)
|
||||
yield f'verify_cell_proof_batch_case_incorrect_row_commitment_{identifier}', {
|
||||
'input': {
|
||||
'row_commitments': encode_hex_list(row_commitments),
|
||||
'row_indices': row_indices,
|
||||
'column_indices': column_indices,
|
||||
'cells': encode_hex_list(cells),
|
||||
'proofs': encode_hex_list(proofs),
|
||||
},
|
||||
'output': False
|
||||
}
|
||||
|
||||
# Incorrect cell
|
||||
cells, proofs = VALID_CELLS_AND_PROOFS[6]
|
||||
cells, proofs = cells[:1], proofs[:1]
|
||||
row_commitments = [VALID_COMMITMENTS[6]]
|
||||
row_indices = [0] * len(cells)
|
||||
column_indices = list(range(len(cells)))
|
||||
# Change last cell so it's wrong
|
||||
cells[-1] = CELL_RANDOM_VALID2
|
||||
assert not spec.verify_cell_proof_batch(row_commitments, row_indices, column_indices, cells, proofs)
|
||||
identifier = make_id(row_commitments, row_indices, column_indices, cells, proofs)
|
||||
yield f'verify_cell_proof_batch_case_incorrect_cell_{identifier}', {
|
||||
'input': {
|
||||
'row_commitments': encode_hex_list(row_commitments),
|
||||
'row_indices': row_indices,
|
||||
'column_indices': column_indices,
|
||||
'cells': encode_hex_list(cells),
|
||||
'proofs': encode_hex_list(proofs),
|
||||
},
|
||||
'output': False
|
||||
}
|
||||
|
||||
# Incorrect proof
|
||||
cells, proofs = VALID_CELLS_AND_PROOFS[0]
|
||||
cells, proofs = cells[:1], proofs[:1]
|
||||
row_commitments = [VALID_COMMITMENTS[0]]
|
||||
row_indices = [0] * len(cells)
|
||||
column_indices = list(range(len(cells)))
|
||||
# Change last proof so it's wrong
|
||||
proofs[-1] = bls_add_one(proofs[-1])
|
||||
assert not spec.verify_cell_proof_batch(row_commitments, row_indices, column_indices, cells, proofs)
|
||||
identifier = make_id(row_commitments, row_indices, column_indices, cells, proofs)
|
||||
yield f'verify_cell_proof_batch_case_incorrect_proof_{identifier}', {
|
||||
'input': {
|
||||
'row_commitments': encode_hex_list(row_commitments),
|
||||
'row_indices': row_indices,
|
||||
'column_indices': column_indices,
|
||||
'cells': encode_hex_list(cells),
|
||||
'proofs': encode_hex_list(proofs),
|
||||
},
|
||||
'output': False
|
||||
}
|
||||
|
||||
# Edge case: Invalid row commitment
|
||||
for i, commitment in enumerate(INVALID_G1_POINTS):
|
||||
cells, proofs = VALID_CELLS_AND_PROOFS[i % len(INVALID_G1_POINTS)]
|
||||
cells, proofs = cells[:1], proofs[:1]
|
||||
# Set row_commitments to the invalid commitment
|
||||
row_commitments = [commitment]
|
||||
row_indices = [0] * len(cells)
|
||||
column_indices = list(range(len(cells)))
|
||||
expect_exception(spec.verify_cell_proof_batch, row_commitments, row_indices, column_indices, cells, proofs)
|
||||
identifier = make_id(row_commitments, row_indices, column_indices, cells, proofs)
|
||||
yield f'verify_cell_proof_batch_case_invalid_row_commitment_{identifier}', {
|
||||
'input': {
|
||||
'row_commitments': encode_hex_list(row_commitments),
|
||||
'row_indices': row_indices,
|
||||
'column_indices': column_indices,
|
||||
'cells': encode_hex_list(cells),
|
||||
'proofs': encode_hex_list(proofs),
|
||||
},
|
||||
'output': None
|
||||
}
|
||||
|
||||
# Edge case: Invalid row_index
|
||||
cells, proofs = VALID_CELLS_AND_PROOFS[0]
|
||||
cells, proofs = cells[:1], proofs[:1]
|
||||
row_commitments = [VALID_COMMITMENTS[0]]
|
||||
row_indices = [0] * len(cells)
|
||||
# Set first row index to an invalid value
|
||||
row_indices[0] = 1
|
||||
column_indices = list(range(len(cells)))
|
||||
expect_exception(spec.verify_cell_proof_batch, row_commitments, row_indices, column_indices, cells, proofs)
|
||||
identifier = make_id(row_commitments, row_indices, column_indices, cells, proofs)
|
||||
yield f'verify_cell_proof_batch_case_invalid_row_index_{identifier}', {
|
||||
'input': {
|
||||
'row_commitments': encode_hex_list(row_commitments),
|
||||
'row_indices': row_indices,
|
||||
'column_indices': column_indices,
|
||||
'cells': encode_hex_list(cells),
|
||||
'proofs': encode_hex_list(proofs),
|
||||
},
|
||||
'output': None
|
||||
}
|
||||
|
||||
# Edge case: Invalid column_index
|
||||
cells, proofs = VALID_CELLS_AND_PROOFS[1]
|
||||
cells, proofs = cells[:1], proofs[:1]
|
||||
row_commitments = [VALID_COMMITMENTS[1]]
|
||||
row_indices = [0] * len(cells)
|
||||
column_indices = list(range(len(cells)))
|
||||
# Set first column index to an invalid value
|
||||
column_indices[0] = spec.CELLS_PER_EXT_BLOB
|
||||
expect_exception(spec.verify_cell_proof_batch, row_commitments, row_indices, column_indices, cells, proofs)
|
||||
identifier = make_id(row_commitments, row_indices, column_indices, cells, proofs)
|
||||
yield f'verify_cell_proof_batch_case_invalid_column_index_{identifier}', {
|
||||
'input': {
|
||||
'row_commitments': encode_hex_list(row_commitments),
|
||||
'row_indices': row_indices,
|
||||
'column_indices': column_indices,
|
||||
'cells': encode_hex_list(cells),
|
||||
'proofs': encode_hex_list(proofs),
|
||||
},
|
||||
'output': None
|
||||
}
|
||||
|
||||
# Edge case: Invalid cell
|
||||
for i, cell in enumerate(INVALID_INDIVIDUAL_CELL_BYTES):
|
||||
cells, proofs = VALID_CELLS_AND_PROOFS[i % len(INVALID_INDIVIDUAL_CELL_BYTES)]
|
||||
cells, proofs = cells[:1], proofs[:1]
|
||||
row_commitments = [VALID_COMMITMENTS[i % len(INVALID_INDIVIDUAL_CELL_BYTES)]]
|
||||
row_indices = [0] * len(cells)
|
||||
column_indices = list(range(len(cells)))
|
||||
# Set first cell to the invalid cell
|
||||
cells[0] = cell
|
||||
expect_exception(spec.verify_cell_proof_batch, row_commitments, row_indices, column_indices, cells, proofs)
|
||||
identifier = make_id(row_commitments, row_indices, column_indices, cells, proofs)
|
||||
yield f'verify_cell_proof_batch_case_invalid_cell_{identifier}', {
|
||||
'input': {
|
||||
'row_commitments': encode_hex_list(row_commitments),
|
||||
'row_indices': row_indices,
|
||||
'column_indices': column_indices,
|
||||
'cells': encode_hex_list(cells),
|
||||
'proofs': encode_hex_list(proofs),
|
||||
},
|
||||
'output': None
|
||||
}
|
||||
|
||||
# Edge case: Invalid proof
|
||||
for i, proof in enumerate(INVALID_G1_POINTS):
|
||||
cells, proofs = VALID_CELLS_AND_PROOFS[i % len(INVALID_G1_POINTS)]
|
||||
cells, proofs = cells[:1], proofs[:1]
|
||||
row_commitments = [VALID_COMMITMENTS[i % len(INVALID_G1_POINTS)]]
|
||||
row_indices = [0] * len(cells)
|
||||
column_indices = list(range(len(cells)))
|
||||
# Set first proof to the invalid proof
|
||||
proofs[0] = proof
|
||||
expect_exception(spec.verify_cell_proof_batch, row_commitments, row_indices, column_indices, cells, proofs)
|
||||
identifier = make_id(row_commitments, row_indices, column_indices, cells, proofs)
|
||||
yield f'verify_cell_proof_batch_case_invalid_proof_{identifier}', {
|
||||
'input': {
|
||||
'row_commitments': encode_hex_list(row_commitments),
|
||||
'row_indices': row_indices,
|
||||
'column_indices': column_indices,
|
||||
'cells': encode_hex_list(cells),
|
||||
'proofs': encode_hex_list(proofs),
|
||||
},
|
||||
'output': None
|
||||
}
|
||||
|
||||
# Edge case: Missing a row commitment
|
||||
cells, proofs = VALID_CELLS_AND_PROOFS[0]
|
||||
cells, proofs = cells[:1], proofs[:1]
|
||||
# Do not include the row commitment
|
||||
row_commitments = []
|
||||
row_indices = [0] * len(cells)
|
||||
column_indices = list(range(len(cells)))
|
||||
expect_exception(spec.verify_cell_proof_batch, row_commitments, row_indices, column_indices, cells, proofs)
|
||||
identifier = make_id(row_commitments, row_indices, column_indices, cells, proofs)
|
||||
yield f'verify_cell_proof_batch_case_invalid_missing_row_commitment_{identifier}', {
|
||||
'input': {
|
||||
'row_commitments': encode_hex_list(row_commitments),
|
||||
'row_indices': row_indices,
|
||||
'column_indices': column_indices,
|
||||
'cells': encode_hex_list(cells),
|
||||
'proofs': encode_hex_list(proofs),
|
||||
},
|
||||
'output': None
|
||||
}
|
||||
|
||||
# Edge case: Missing a row index
|
||||
cells, proofs = VALID_CELLS_AND_PROOFS[1]
|
||||
cells, proofs = cells[:2], proofs[:2]
|
||||
row_commitments = [VALID_COMMITMENTS[1]]
|
||||
# Leave off one of the row indices
|
||||
row_indices = [0] * (len(cells) - 1)
|
||||
column_indices = list(range(len(cells)))
|
||||
expect_exception(spec.verify_cell_proof_batch, row_commitments, row_indices, column_indices, cells, proofs)
|
||||
identifier = make_id(row_commitments, row_indices, column_indices, cells, proofs)
|
||||
yield f'verify_cell_proof_batch_case_invalid_missing_row_index_{identifier}', {
|
||||
'input': {
|
||||
'row_commitments': encode_hex_list(row_commitments),
|
||||
'row_indices': row_indices,
|
||||
'column_indices': column_indices,
|
||||
'cells': encode_hex_list(cells),
|
||||
'proofs': encode_hex_list(proofs),
|
||||
},
|
||||
'output': None
|
||||
}
|
||||
|
||||
# Edge case: Missing a column index
|
||||
cells, proofs = VALID_CELLS_AND_PROOFS[2]
|
||||
cells, proofs = cells[:2], proofs[:2]
|
||||
row_commitments = [VALID_COMMITMENTS[2]]
|
||||
row_indices = [0] * len(cells)
|
||||
# Leave off one of the column indices
|
||||
column_indices = list(range(len(cells) - 1))
|
||||
expect_exception(spec.verify_cell_proof_batch, row_commitments, row_indices, column_indices, cells, proofs)
|
||||
identifier = make_id(row_commitments, row_indices, column_indices, cells, proofs)
|
||||
yield f'verify_cell_proof_batch_case_invalid_missing_column_index_{identifier}', {
|
||||
'input': {
|
||||
'row_commitments': encode_hex_list(row_commitments),
|
||||
'row_indices': row_indices,
|
||||
'column_indices': column_indices,
|
||||
'cells': encode_hex_list(cells),
|
||||
'proofs': encode_hex_list(proofs),
|
||||
},
|
||||
'output': None
|
||||
}
|
||||
|
||||
# Edge case: Missing a cell
|
||||
cells, proofs = VALID_CELLS_AND_PROOFS[3]
|
||||
cells, proofs = cells[:2], proofs[:2]
|
||||
row_commitments = [VALID_COMMITMENTS[3]]
|
||||
row_indices = [0] * len(cells)
|
||||
column_indices = list(range(len(cells)))
|
||||
# Remove the last proof
|
||||
cells = cells[:-1]
|
||||
expect_exception(spec.verify_cell_proof_batch, row_commitments, row_indices, column_indices, cells, proofs)
|
||||
identifier = make_id(row_commitments, row_indices, column_indices, cells, proofs)
|
||||
yield f'verify_cell_proof_batch_case_invalid_missing_cell_{identifier}', {
|
||||
'input': {
|
||||
'row_commitments': encode_hex_list(row_commitments),
|
||||
'row_indices': row_indices,
|
||||
'column_indices': column_indices,
|
||||
'cells': encode_hex_list(cells),
|
||||
'proofs': encode_hex_list(proofs),
|
||||
},
|
||||
'output': None
|
||||
}
|
||||
|
||||
# Edge case: Missing a proof
|
||||
cells, proofs = VALID_CELLS_AND_PROOFS[4]
|
||||
cells, proofs = cells[:2], proofs[:2]
|
||||
row_commitments = [VALID_COMMITMENTS[4]]
|
||||
row_indices = [0] * len(cells)
|
||||
column_indices = list(range(len(cells)))
|
||||
# Remove the last proof
|
||||
proofs = proofs[:-1]
|
||||
expect_exception(spec.verify_cell_proof_batch, row_commitments, row_indices, column_indices, cells, proofs)
|
||||
identifier = make_id(row_commitments, row_indices, column_indices, cells, proofs)
|
||||
yield f'verify_cell_proof_batch_case_invalid_missing_proof_{identifier}', {
|
||||
'input': {
|
||||
'row_commitments': encode_hex_list(row_commitments),
|
||||
'row_indices': row_indices,
|
||||
'column_indices': column_indices,
|
||||
'cells': encode_hex_list(cells),
|
||||
'proofs': encode_hex_list(proofs),
|
||||
},
|
||||
'output': None
|
||||
}
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Test cases for recover_all_cells
|
||||
###############################################################################
|
||||
|
||||
def case05_recover_all_cells():
|
||||
# Valid: No missing cells
|
||||
blob = BLOB_RANDOM_VALID1
|
||||
cells = spec.compute_cells(blob)
|
||||
cell_ids = list(range(spec.CELLS_PER_EXT_BLOB))
|
||||
recovered_cells = spec.recover_all_cells(cell_ids, cells)
|
||||
assert recovered_cells == cells
|
||||
identifier = make_id(cell_ids, cells)
|
||||
yield f'recover_all_cells_case_valid_no_missing_{identifier}', {
|
||||
'input': {
|
||||
'cell_ids': cell_ids,
|
||||
'cells': encode_hex_list(cells),
|
||||
},
|
||||
'output': encode_hex_list(recovered_cells)
|
||||
}
|
||||
|
||||
# Valid: Half missing cells (every other cell)
|
||||
blob = BLOB_RANDOM_VALID2
|
||||
cells = spec.compute_cells(blob)
|
||||
cell_ids = list(range(0, spec.CELLS_PER_EXT_BLOB, 2))
|
||||
partial_cells = [cells[cell_id] for cell_id in cell_ids]
|
||||
recovered_cells = spec.recover_all_cells(cell_ids, partial_cells)
|
||||
assert recovered_cells == cells
|
||||
identifier = make_id(cell_ids, partial_cells)
|
||||
yield f'recover_all_cells_case_valid_half_missing_every_other_cell_{identifier}', {
|
||||
'input': {
|
||||
'cell_ids': cell_ids,
|
||||
'cells': encode_hex_list(partial_cells),
|
||||
},
|
||||
'output': encode_hex_list(recovered_cells)
|
||||
}
|
||||
|
||||
# Valid: Half missing cells (first half)
|
||||
blob = BLOB_RANDOM_VALID3
|
||||
cells = spec.compute_cells(blob)
|
||||
cell_ids = list(range(0, spec.CELLS_PER_EXT_BLOB // 2))
|
||||
partial_cells = [cells[cell_id] for cell_id in cell_ids]
|
||||
recovered_cells = spec.recover_all_cells(cell_ids, partial_cells)
|
||||
assert recovered_cells == cells
|
||||
identifier = make_id(cell_ids, partial_cells)
|
||||
yield f'recover_all_cells_case_valid_half_missing_first_half_{identifier}', {
|
||||
'input': {
|
||||
'cell_ids': cell_ids,
|
||||
'cells': encode_hex_list(partial_cells),
|
||||
},
|
||||
'output': encode_hex_list(recovered_cells)
|
||||
}
|
||||
|
||||
# Valid: Half missing cells (second half)
|
||||
blob = BLOB_RANDOM_VALID1
|
||||
cells = spec.compute_cells(blob)
|
||||
cell_ids = list(range(spec.CELLS_PER_EXT_BLOB // 2, spec.CELLS_PER_EXT_BLOB))
|
||||
partial_cells = [cells[cell_id] for cell_id in cell_ids]
|
||||
recovered_cells = spec.recover_all_cells(cell_ids, partial_cells)
|
||||
assert recovered_cells == cells
|
||||
identifier = make_id(cell_ids, partial_cells)
|
||||
yield f'recover_all_cells_case_valid_half_missing_second_half_{identifier}', {
|
||||
'input': {
|
||||
'cell_ids': cell_ids,
|
||||
'cells': encode_hex_list(partial_cells),
|
||||
},
|
||||
'output': encode_hex_list(recovered_cells)
|
||||
}
|
||||
|
||||
# Edge case: All cells are missing
|
||||
cell_ids, partial_cells = [], []
|
||||
expect_exception(spec.recover_all_cells, cell_ids, partial_cells)
|
||||
identifier = make_id(cell_ids, partial_cells)
|
||||
yield f'recover_all_cells_case_invalid_all_cells_are_missing_{identifier}', {
|
||||
'input': {
|
||||
'cell_ids': cell_ids,
|
||||
'cells': encode_hex_list(partial_cells),
|
||||
},
|
||||
'output': None
|
||||
}
|
||||
|
||||
# Edge case: More than half missing
|
||||
blob = BLOB_RANDOM_VALID2
|
||||
cells = spec.compute_cells(blob)
|
||||
cell_ids = list(range(spec.CELLS_PER_EXT_BLOB // 2 - 1))
|
||||
partial_cells = [cells[cell_id] for cell_id in cell_ids]
|
||||
expect_exception(spec.recover_all_cells, cell_ids, partial_cells)
|
||||
identifier = make_id(cell_ids, partial_cells)
|
||||
yield f'recover_all_cells_case_invalid_more_than_half_missing_{identifier}', {
|
||||
'input': {
|
||||
'cell_ids': cell_ids,
|
||||
'cells': encode_hex_list(partial_cells),
|
||||
},
|
||||
'output': None
|
||||
}
|
||||
|
||||
# Edge case: Invalid cell_id
|
||||
blob = BLOB_RANDOM_VALID1
|
||||
cells = spec.compute_cells(blob)
|
||||
cell_ids = list(range(spec.CELLS_PER_EXT_BLOB // 2))
|
||||
partial_cells = [cells[cell_id] for cell_id in cell_ids]
|
||||
# Replace first cell_id with an invalid value
|
||||
cell_ids[0] = spec.CELLS_PER_EXT_BLOB
|
||||
expect_exception(spec.recover_all_cells, cell_ids, partial_cells)
|
||||
identifier = make_id(cell_ids, partial_cells)
|
||||
yield f'recover_all_cells_case_invalid_cell_id_{identifier}', {
|
||||
'input': {
|
||||
'cell_ids': cell_ids,
|
||||
'cells': encode_hex_list(partial_cells),
|
||||
},
|
||||
'output': None
|
||||
}
|
||||
|
||||
# Edge case: Invalid cell
|
||||
blob = BLOB_RANDOM_VALID2
|
||||
for cell in INVALID_INDIVIDUAL_CELL_BYTES:
|
||||
cells = spec.compute_cells(blob)
|
||||
cell_ids = list(range(spec.CELLS_PER_EXT_BLOB // 2))
|
||||
partial_cells = [cells[cell_id] for cell_id in cell_ids]
|
||||
# Replace first cell with an invalid value
|
||||
partial_cells[0] = cell
|
||||
expect_exception(spec.recover_all_cells, cell_ids, partial_cells)
|
||||
identifier = make_id(cell_ids, partial_cells)
|
||||
yield f'recover_all_cells_case_invalid_cell_{identifier}', {
|
||||
'input': {
|
||||
'cell_ids': cell_ids,
|
||||
'cells': encode_hex_list(partial_cells),
|
||||
},
|
||||
'output': None
|
||||
}
|
||||
|
||||
# Edge case: More cell_ids than cells
|
||||
blob = BLOB_RANDOM_VALID3
|
||||
cells = spec.compute_cells(blob)
|
||||
cell_ids = list(range(0, spec.CELLS_PER_EXT_BLOB, 2))
|
||||
partial_cells = [cells[cell_id] for cell_id in cell_ids]
|
||||
# Add another cell_id
|
||||
cell_ids.append(spec.CELLS_PER_EXT_BLOB - 1)
|
||||
expect_exception(spec.recover_all_cells, cell_ids, partial_cells)
|
||||
identifier = make_id(cell_ids, partial_cells)
|
||||
yield f'recover_all_cells_case_invalid_more_cell_ids_than_cells_{identifier}', {
|
||||
'input': {
|
||||
'cell_ids': cell_ids,
|
||||
'cells': encode_hex_list(partial_cells),
|
||||
},
|
||||
'output': None
|
||||
}
|
||||
|
||||
# Edge case: More cells than cell_ids
|
||||
blob = BLOB_RANDOM_VALID1
|
||||
cells = spec.compute_cells(blob)
|
||||
cell_ids = list(range(0, spec.CELLS_PER_EXT_BLOB, 2))
|
||||
partial_cells = [cells[cell_id] for cell_id in cell_ids]
|
||||
# Add another cell
|
||||
partial_cells.append(CELL_RANDOM_VALID1)
|
||||
expect_exception(spec.recover_all_cells, cell_ids, partial_cells)
|
||||
identifier = make_id(cell_ids, partial_cells)
|
||||
yield f'recover_all_cells_case_invalid_more_cells_than_cell_ids_{identifier}', {
|
||||
'input': {
|
||||
'cell_ids': cell_ids,
|
||||
'cells': encode_hex_list(partial_cells),
|
||||
},
|
||||
'output': None
|
||||
}
|
||||
|
||||
# Edge case: Duplicate cell_id
|
||||
blob = BLOB_RANDOM_VALID2
|
||||
cells = spec.compute_cells(blob)
|
||||
cell_ids = list(range(spec.CELLS_PER_EXT_BLOB // 2))
|
||||
partial_cells = [cells[cell_id] for cell_id in cell_ids]
|
||||
# Replace first cell_id with the second cell_id
|
||||
cell_ids[0] = cell_ids[1]
|
||||
expect_exception(spec.recover_all_cells, cell_ids, partial_cells)
|
||||
identifier = make_id(cell_ids, partial_cells)
|
||||
yield f'recover_all_cells_case_invalid_duplicate_cell_id_{identifier}', {
|
||||
'input': {
|
||||
'cell_ids': cell_ids,
|
||||
'cells': encode_hex_list(partial_cells),
|
||||
},
|
||||
'output': None
|
||||
}
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Main logic
|
||||
###############################################################################
|
||||
|
||||
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,
|
||||
suite_name='kzg-mainnet',
|
||||
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_7594", [
|
||||
# EIP-7594
|
||||
create_provider(EIP7594, 'compute_cells', case01_compute_cells),
|
||||
create_provider(EIP7594, 'compute_cells_and_proofs', case02_compute_cells_and_proofs),
|
||||
create_provider(EIP7594, 'verify_cell_proof', case03_verify_cell_proof),
|
||||
create_provider(EIP7594, 'verify_cell_proof_batch', case04_verify_cell_proof_batch),
|
||||
create_provider(EIP7594, 'recover_all_cells', case05_recover_all_cells),
|
||||
])
|
|
@ -0,0 +1,2 @@
|
|||
pytest>=4.4
|
||||
../../../[generator]
|
Loading…
Reference in New Issue