From b692a47f7bc3cf4b0eaeb8d73bfc9fb621e6745c Mon Sep 17 00:00:00 2001 From: Daniel Sanchez Quiros Date: Tue, 13 Feb 2024 13:06:24 +0100 Subject: [PATCH] Added g1_linecomb without strict limit assertion --- da/kzg_rs.py | 20 +++++++++++++++++--- da/test_kzg_rs.py | 7 +++++++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/da/kzg_rs.py b/da/kzg_rs.py index 5fb5649..c92f951 100644 --- a/da/kzg_rs.py +++ b/da/kzg_rs.py @@ -1,17 +1,31 @@ from itertools import batched -from typing import List +from typing import List, Sequence from eth2spec.eip7594.mainnet import ( - blob_to_kzg_commitment, g1_lincomb, bit_reversal_permutation, KZG_SETUP_G1_LAGRANGE, Polynomial, + bit_reversal_permutation, KZG_SETUP_G1_LAGRANGE, Polynomial, BYTES_PER_FIELD_ELEMENT, bytes_to_bls_field, BLSFieldElement, ) from eth2spec.eip7594.mainnet import KZGCommitment as Commitment, KZGProof as Proof +from eth2spec.utils import bls class Polynomial(List[BLSFieldElement]): pass +def g1_lincomb(points: Sequence[Commitment], scalars: Sequence[BLSFieldElement]) -> Commitment: + """ + BLS multiscalar multiplication. This function can be optimized using Pippenger's algorithm and variants. + """ + # we assert to have more points available than elements, + # this is dependent on the available kzg setup size + assert len(points) >= len(scalars) + result = bls.Z1() + for x, a in zip(points, scalars): + result = bls.add(result, bls.multiply(bls.bytes48_to_G1(x), a)) + return Commitment(bls.G1_to_bytes48(result)) + + def bytes_to_polynomial(b: bytearray) -> Polynomial: """ Convert bytes to list of BLS field scalars. @@ -23,4 +37,4 @@ def bytes_to_polynomial(b: bytearray) -> Polynomial: def bytes_to_kzg_commitment(b: bytearray) -> Commitment: return g1_lincomb( bit_reversal_permutation(KZG_SETUP_G1_LAGRANGE), bytes_to_polynomial(b) - ) + ) \ No newline at end of file diff --git a/da/test_kzg_rs.py b/da/test_kzg_rs.py index bc7dc38..d3daadc 100644 --- a/da/test_kzg_rs.py +++ b/da/test_kzg_rs.py @@ -30,3 +30,10 @@ class TestKzgRs(TestCase): eth_commitment = blob_to_kzg_commitment(Blob(rand_bytes)) commitment = bytes_to_kzg_commitment(rand_bytes) self.assertEqual(eth_commitment, commitment) + + def test_small_bytes_kzg_commitment(self): + rand_bytes = bytearray(int.to_bytes(randrange(BLS_MODULUS), length=BYTES_PER_FIELD_ELEMENT)) + commitment = bytes_to_kzg_commitment(rand_bytes) + rand_bytes = self.rand_bytes() + commitment2 = bytes_to_kzg_commitment(rand_bytes) + self.assertEqual(len(commitment), len(commitment2))