diff --git a/da/common.py b/da/common.py index 72388b2..0a219ed 100644 --- a/da/common.py +++ b/da/common.py @@ -1,10 +1,10 @@ from dataclasses import dataclass -from itertools import chain, zip_longest -from typing import List, Generator, Self - - +from hashlib import sha3_256 +from itertools import chain, zip_longest, compress +from typing import List, Generator, Self, Sequence from eth2spec.eip7594.mainnet import Bytes32, KZGCommitment as Commitment +from py_ecc.bls import G2ProofOfPossession as bls_pop class NodeId(Bytes32): @@ -55,3 +55,16 @@ class Certificate: aggregated_column_commitment: Commitment row_commitments: List[Commitment] + def verify(self, nodes_public_keys: List[BLSPublickey]) -> bool: + # we short them as the signers bitfield is sorted by the public keys as well + signers_keys = list(compress(sorted(nodes_public_keys), self.signers)) + message = build_attestation_message(self.aggregated_column_commitment, self.row_commitments) + return bls_pop.AggregateVerify(signers_keys, [message]*len(signers_keys), self.aggregated_signatures) + + +def build_attestation_message(aggregated_column_commitment: Commitment, row_commitments: Sequence[Commitment]) -> bytes: + hasher = sha3_256() + hasher.update(bytes(aggregated_column_commitment)) + for c in row_commitments: + hasher.update(bytes(c)) + return hasher.digest() \ No newline at end of file diff --git a/da/dispersal.py b/da/dispersal.py index aade4f9..9a6fb12 100644 --- a/da/dispersal.py +++ b/da/dispersal.py @@ -4,7 +4,7 @@ from typing import List, Optional, Generator, Sequence from py_ecc.bls import G2ProofOfPossession as bls_pop -from da.common import Certificate, NodeId, BLSPublickey, Bitfield +from da.common import Certificate, NodeId, BLSPublickey, Bitfield, build_attestation_message from da.encoder import EncodedData from da.verifier import DABlob, Attestation @@ -19,9 +19,9 @@ class DispersalSettings: class Dispersal: def __init__(self, settings: DispersalSettings): self.settings = settings - # sort nodes_ids and related public keys + # sort over public keys self.settings.nodes_ids, self.settings.nodes_pubkey = zip( - *sorted(zip(self.settings.nodes_ids, self.settings.nodes_pubkey), key=lambda x: x[0]) + *sorted(zip(self.settings.nodes_ids, self.settings.nodes_pubkey), key=lambda x: x[1]) ) def _prepare_data(self, encoded_data: EncodedData) -> Generator[DABlob, None, None]: @@ -71,11 +71,7 @@ class Dispersal: @staticmethod def _build_attestation_message(encoded_data: EncodedData) -> bytes: - hasher = sha3_256() - hasher.update(bytes(encoded_data.aggregated_column_commitment)) - for c in encoded_data.row_commitments: - hasher.update(bytes(c)) - return hasher.digest() + return build_attestation_message(encoded_data.aggregated_column_commitment, encoded_data.row_commitments) def disperse(self, encoded_data: EncodedData) -> Optional[Certificate]: attestations = [] diff --git a/da/test_dispersal.py b/da/test_dispersal.py index dabe830..4fd4029 100644 --- a/da/test_dispersal.py +++ b/da/test_dispersal.py @@ -46,7 +46,7 @@ class TestDispersal(TestCase): self.assertEqual(certificate.row_commitments, []) self.assertIsNotNone(certificate.aggregated_signatures) self.assertTrue( - bls_pop.AggregateVerify(self.public_keys, [mock_message]*len(self.public_keys), certificate.aggregated_signatures) + certificate.verify(self.public_keys) ) def test_disperse(self): @@ -64,12 +64,7 @@ class TestDispersal(TestCase): certificate = self.dispersal.disperse(encoded_data) self.assertIsNotNone(certificate) - self.assertTrue( - bls_pop.AggregateVerify( - self.public_keys[:self.dispersal.settings.threshold], - [self.dispersal._build_attestation_message(encoded_data)]*self.dispersal.settings.threshold, - certificate.aggregated_signatures - ) + self.assertTrue(certificate.verify(self.public_keys) ) self.assertEqual( certificate.signers,