Use chunks for verification
This commit is contained in:
parent
0f27a16468
commit
eecda172b8
|
@ -1,4 +1,5 @@
|
|||
from dataclasses import dataclass
|
||||
from itertools import chain
|
||||
from typing import List, Generator
|
||||
|
||||
from eth2spec.eip7594.mainnet import Bytes32
|
||||
|
@ -16,7 +17,8 @@ class Column(List[Bytes32]):
|
|||
|
||||
|
||||
class Row(List[Bytes32]):
|
||||
pass
|
||||
def as_bytes(self) -> bytes:
|
||||
return bytes(chain.from_iterable(self))
|
||||
|
||||
|
||||
class ChunksMatrix(List[Row]):
|
||||
|
|
|
@ -3,7 +3,7 @@ from itertools import batched, chain
|
|||
from typing import List, Sequence, Tuple
|
||||
from eth2spec.eip7594.mainnet import KZGCommitment as Commitment, KZGProof as Proof, BLSFieldElement
|
||||
|
||||
from da.common import ChunksMatrix, Chunk
|
||||
from da.common import ChunksMatrix, Chunk, Row
|
||||
from da.kzg_rs import kzg, rs, poly
|
||||
from da.kzg_rs.common import GLOBAL_PARAMETERS, ROOTS_OF_UNITY
|
||||
from da.kzg_rs.poly import Polynomial
|
||||
|
@ -32,22 +32,23 @@ class DAEncoder:
|
|||
|
||||
def _chunkify_data(self, data: bytes) -> ChunksMatrix:
|
||||
size: int = self.params.column_count * self.params.bytes_per_field_element
|
||||
return ChunksMatrix(bytes(b) for b in batched(data, size))
|
||||
return ChunksMatrix(
|
||||
Row([bytes(chunk) for chunk in batched(b, self.params.bytes_per_field_element)])
|
||||
for b in batched(data, size)
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _compute_row_kzg_commitments(rows: Sequence[bytes]) -> List[Tuple[Polynomial, Commitment]]:
|
||||
return [kzg.bytes_to_commitment(row, GLOBAL_PARAMETERS) for row in rows]
|
||||
def _compute_row_kzg_commitments(rows: Sequence[Row]) -> List[Tuple[Polynomial, Commitment]]:
|
||||
return [kzg.bytes_to_commitment(row.as_bytes(), GLOBAL_PARAMETERS) for row in rows]
|
||||
|
||||
def _rs_encode_rows(self, chunks_matrix: ChunksMatrix) -> ChunksMatrix:
|
||||
def __rs_encode_row(row: bytes) -> bytes:
|
||||
polynomial = kzg.bytes_to_polynomial(row)
|
||||
return bytes(
|
||||
chain.from_iterable(
|
||||
Chunk(BLSFieldElement.to_bytes(
|
||||
x,
|
||||
length=self.params.bytes_per_field_element, byteorder="big"
|
||||
)) for x in rs.encode(polynomial, 2, ROOTS_OF_UNITY)
|
||||
)
|
||||
def __rs_encode_row(row: Row) -> Row:
|
||||
polynomial = kzg.bytes_to_polynomial(row.as_bytes())
|
||||
return Row(
|
||||
Chunk(BLSFieldElement.to_bytes(
|
||||
x,
|
||||
length=self.params.bytes_per_field_element, byteorder="big"
|
||||
)) for x in rs.encode(polynomial, 2, ROOTS_OF_UNITY)
|
||||
)
|
||||
return ChunksMatrix(__rs_encode_row(row) for row in chunks_matrix)
|
||||
|
||||
|
@ -61,7 +62,7 @@ class DAEncoder:
|
|||
proofs.append(
|
||||
[
|
||||
kzg.generate_element_proof(i, poly, GLOBAL_PARAMETERS, ROOTS_OF_UNITY)
|
||||
for i in range(len(row)//self.params.bytes_per_field_element)
|
||||
for i in range(len(row))
|
||||
]
|
||||
)
|
||||
return proofs
|
||||
|
|
|
@ -54,14 +54,14 @@ def generate_element_proof(
|
|||
|
||||
|
||||
def verify_element_proof(
|
||||
polynomial: Polynomial,
|
||||
chunk: BLSFieldElement,
|
||||
commitment: Commitment,
|
||||
proof: Proof,
|
||||
element_index: int,
|
||||
roots_of_unity: Sequence[BLSFieldElement],
|
||||
) -> bool:
|
||||
u = int(roots_of_unity[element_index])
|
||||
v = polynomial.eval(u)
|
||||
v = chunk
|
||||
commitment_check_G1 = bls.bytes48_to_G1(commitment) - bls.multiply(bls.G1(), v)
|
||||
proof_check_g2 = bls.add(
|
||||
GLOBAL_PARAMETERS_G2[1],
|
||||
|
|
|
@ -2,7 +2,7 @@ from itertools import chain, batched
|
|||
from random import randrange
|
||||
from unittest import TestCase
|
||||
|
||||
from eth2spec.deneb.mainnet import BLS_MODULUS, bytes_to_bls_field
|
||||
from eth2spec.deneb.mainnet import BLS_MODULUS, bytes_to_bls_field, BLSFieldElement
|
||||
|
||||
from da.kzg_rs import kzg
|
||||
from da.kzg_rs.common import BYTES_PER_FIELD_ELEMENT, GLOBAL_PARAMETERS, ROOTS_OF_UNITY, GLOBAL_PARAMETERS_G2
|
||||
|
@ -12,11 +12,11 @@ from da.kzg_rs.trusted_setup import verify_setup
|
|||
class TestKZG(TestCase):
|
||||
|
||||
@staticmethod
|
||||
def rand_bytes(size=1024):
|
||||
return bytearray(
|
||||
def rand_bytes(n_chunks=1024):
|
||||
return bytes(
|
||||
chain.from_iterable(
|
||||
int.to_bytes(randrange(BLS_MODULUS), length=BYTES_PER_FIELD_ELEMENT)
|
||||
for _ in range(size)
|
||||
for _ in range(n_chunks)
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -24,11 +24,15 @@ class TestKZG(TestCase):
|
|||
self.assertTrue(verify_setup((GLOBAL_PARAMETERS, GLOBAL_PARAMETERS_G2)))
|
||||
|
||||
def test_poly_forms(self):
|
||||
rand_bytes = self.rand_bytes(8)
|
||||
n_chunks = 16
|
||||
rand_bytes = self.rand_bytes(n_chunks)
|
||||
eval_form = [int(bytes_to_bls_field(b)) for b in batched(rand_bytes, int(BYTES_PER_FIELD_ELEMENT))]
|
||||
poly = kzg.bytes_to_polynomial(rand_bytes)
|
||||
self.assertEqual(poly.evaluation_form(), eval_form)
|
||||
self.assertEqual(poly.evaluation_form()[0], poly.eval(int(ROOTS_OF_UNITY[0])))
|
||||
for i, chunk in enumerate(eval_form):
|
||||
self.assertEqual(poly.eval(ROOTS_OF_UNITY[i]), chunk)
|
||||
for i in range(n_chunks):
|
||||
self.assertEqual(poly.evaluation_form()[i], poly.eval(int(ROOTS_OF_UNITY[i])))
|
||||
|
||||
def test_commitment(self):
|
||||
rand_bytes = self.rand_bytes(32)
|
||||
|
@ -46,16 +50,18 @@ class TestKZG(TestCase):
|
|||
rand_bytes = self.rand_bytes(n_chunks)
|
||||
_, commit = kzg.bytes_to_commitment(rand_bytes, GLOBAL_PARAMETERS)
|
||||
poly = kzg.bytes_to_polynomial(rand_bytes)
|
||||
for n in range(n_chunks):
|
||||
proof = kzg.generate_element_proof(n, poly, GLOBAL_PARAMETERS, ROOTS_OF_UNITY)
|
||||
for i, chunk in enumerate(batched(rand_bytes, BYTES_PER_FIELD_ELEMENT)):
|
||||
chunk = bytes(chunk)
|
||||
proof = kzg.generate_element_proof(i, poly, GLOBAL_PARAMETERS, ROOTS_OF_UNITY)
|
||||
self.assertEqual(len(proof), 48)
|
||||
self.assertEqual(poly.eval(int(ROOTS_OF_UNITY[i])), bytes_to_bls_field(chunk))
|
||||
self.assertTrue(kzg.verify_element_proof(
|
||||
poly, commit, proof, n, ROOTS_OF_UNITY
|
||||
bytes_to_bls_field(chunk), commit, proof, i, ROOTS_OF_UNITY
|
||||
)
|
||||
)
|
||||
proof = kzg.generate_element_proof(0, poly, GLOBAL_PARAMETERS, ROOTS_OF_UNITY)
|
||||
for n in range(1, n_chunks):
|
||||
self.assertFalse(kzg.verify_element_proof(
|
||||
poly, commit, proof, n, ROOTS_OF_UNITY
|
||||
BLSFieldElement(0), commit, proof, n, ROOTS_OF_UNITY
|
||||
)
|
||||
)
|
|
@ -37,8 +37,9 @@ class TestEncoder(TestCase):
|
|||
_encoder = encoder.DAEncoder(encoder_settings)
|
||||
chunks_matrix = _encoder._chunkify_data(data)
|
||||
self.assertEqual(len(chunks_matrix), elements//encoder_settings.column_count)
|
||||
for column in chunks_matrix:
|
||||
self.assertEqual(len(column), encoder_settings.bytes_per_field_element*encoder_settings.column_count)
|
||||
for row in chunks_matrix:
|
||||
self.assertEqual(len(row), encoder_settings.column_count)
|
||||
self.assertEqual(len(row[0]), encoder_settings.bytes_per_field_element)
|
||||
|
||||
def test_compute_row_kzg_commitments(self):
|
||||
chunks_matrix = self.encoder._chunkify_data(self.data)
|
||||
|
@ -50,8 +51,8 @@ class TestEncoder(TestCase):
|
|||
extended_chunks_matrix = self.encoder._rs_encode_rows(chunks_matrix)
|
||||
for r1, r2 in zip(chunks_matrix, extended_chunks_matrix):
|
||||
self.assertEqual(len(r1), len(r2)//2)
|
||||
r2 = [BLSFieldElement.from_bytes(x) for x in batched(r2, self.params.bytes_per_field_element)]
|
||||
poly_1 = kzg.bytes_to_polynomial(r1)
|
||||
r2 = [BLSFieldElement.from_bytes(x) for x in r2]
|
||||
poly_1 = kzg.bytes_to_polynomial(r1.as_bytes())
|
||||
# we check against decoding so we now the encoding was properly done
|
||||
poly_2 = rs.decode(r2, ROOTS_OF_UNITY, len(poly_1))
|
||||
self.assertEqual(poly_1, poly_2)
|
||||
|
@ -64,12 +65,13 @@ class TestEncoder(TestCase):
|
|||
extended_proofs = self.encoder._compute_rows_proofs(extended_chunks_matrix, polynomials, commitments)
|
||||
# check original sized matrix
|
||||
for row, poly, commitment, proofs in zip(chunks_matrix, polynomials, commitments, original_proofs):
|
||||
for i in range(len(proofs)):
|
||||
self.assertTrue(kzg.verify_element_proof(poly, commitment, proofs[i], i, ROOTS_OF_UNITY))
|
||||
self.assertEqual(len(proofs), len(row))
|
||||
for i, chunk in enumerate(row):
|
||||
self.assertTrue(kzg.verify_element_proof(BLSFieldElement.from_bytes(chunk), commitment, proofs[i], i, ROOTS_OF_UNITY))
|
||||
# check extended matrix
|
||||
for row, poly, commitment, proofs in zip(extended_chunks_matrix, polynomials, commitments, extended_proofs):
|
||||
for i in range(len(proofs)):
|
||||
self.assertTrue(kzg.verify_element_proof(poly, commitment, proofs[i], i, ROOTS_OF_UNITY))
|
||||
for i, chunk in enumerate(row):
|
||||
self.assertTrue(kzg.verify_element_proof(BLSFieldElement.from_bytes(chunk), commitment, proofs[i], i, ROOTS_OF_UNITY))
|
||||
|
||||
def test_compute_column_kzg_commitments(self):
|
||||
pass
|
||||
|
|
Loading…
Reference in New Issue