mirror of
https://github.com/logos-co/nomos-specs.git
synced 2025-02-09 05:54:16 +00:00
Added verification to certificate (#82)
* Added verification method to certificate * Update da/common.py typo short -> sort Co-authored-by: gusto <bacv@users.noreply.github.com> * Fix test imports * Added verification comment --------- Co-authored-by: gusto <bacv@users.noreply.github.com>
This commit is contained in:
parent
bd964e7b27
commit
0e142c0888
26
da/common.py
26
da/common.py
@ -1,10 +1,10 @@
|
|||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from itertools import chain, zip_longest
|
from hashlib import sha3_256
|
||||||
from typing import List, Generator, Self
|
from itertools import chain, zip_longest, compress
|
||||||
|
from typing import List, Generator, Self, Sequence
|
||||||
|
|
||||||
|
|
||||||
from eth2spec.eip7594.mainnet import Bytes32, KZGCommitment as Commitment
|
from eth2spec.eip7594.mainnet import Bytes32, KZGCommitment as Commitment
|
||||||
|
from py_ecc.bls import G2ProofOfPossession as bls_pop
|
||||||
|
|
||||||
|
|
||||||
class NodeId(Bytes32):
|
class NodeId(Bytes32):
|
||||||
@ -55,3 +55,21 @@ class Certificate:
|
|||||||
aggregated_column_commitment: Commitment
|
aggregated_column_commitment: Commitment
|
||||||
row_commitments: List[Commitment]
|
row_commitments: List[Commitment]
|
||||||
|
|
||||||
|
def verify(self, nodes_public_keys: List[BLSPublickey]) -> bool:
|
||||||
|
"""
|
||||||
|
List of nodes public keys should be a trusted list of verified proof of possession keys.
|
||||||
|
Otherwise, we could fall under the Rogue Key Attack
|
||||||
|
`assert all(bls_pop.PopVerify(pk, proof) for pk, proof in zip(node_public_keys, pops))`
|
||||||
|
"""
|
||||||
|
# we sort 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()
|
@ -4,7 +4,7 @@ from typing import List, Optional, Generator, Sequence
|
|||||||
|
|
||||||
from py_ecc.bls import G2ProofOfPossession as bls_pop
|
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.encoder import EncodedData
|
||||||
from da.verifier import DABlob, Attestation
|
from da.verifier import DABlob, Attestation
|
||||||
|
|
||||||
@ -19,9 +19,9 @@ class DispersalSettings:
|
|||||||
class Dispersal:
|
class Dispersal:
|
||||||
def __init__(self, settings: DispersalSettings):
|
def __init__(self, settings: DispersalSettings):
|
||||||
self.settings = settings
|
self.settings = settings
|
||||||
# sort nodes_ids and related public keys
|
# sort over public keys
|
||||||
self.settings.nodes_ids, self.settings.nodes_pubkey = zip(
|
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]:
|
def _prepare_data(self, encoded_data: EncodedData) -> Generator[DABlob, None, None]:
|
||||||
@ -71,11 +71,7 @@ class Dispersal:
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _build_attestation_message(encoded_data: EncodedData) -> bytes:
|
def _build_attestation_message(encoded_data: EncodedData) -> bytes:
|
||||||
hasher = sha3_256()
|
return build_attestation_message(encoded_data.aggregated_column_commitment, encoded_data.row_commitments)
|
||||||
hasher.update(bytes(encoded_data.aggregated_column_commitment))
|
|
||||||
for c in encoded_data.row_commitments:
|
|
||||||
hasher.update(bytes(c))
|
|
||||||
return hasher.digest()
|
|
||||||
|
|
||||||
def disperse(self, encoded_data: EncodedData) -> Optional[Certificate]:
|
def disperse(self, encoded_data: EncodedData) -> Optional[Certificate]:
|
||||||
attestations = []
|
attestations = []
|
||||||
|
@ -1,14 +1,13 @@
|
|||||||
from hashlib import sha3_256
|
from hashlib import sha3_256
|
||||||
from unittest import TestCase
|
from unittest import TestCase
|
||||||
|
|
||||||
from .encoder import DAEncoderParams, DAEncoder
|
from da.encoder import DAEncoderParams, DAEncoder
|
||||||
from .test_encoder import TestEncoder
|
from da.test_encoder import TestEncoder
|
||||||
|
from da.verifier import DAVerifier, DABlob
|
||||||
from da.common import NodeId, Attestation, Bitfield
|
from da.common import NodeId, Attestation, Bitfield
|
||||||
from da.dispersal import Dispersal, EncodedData, DispersalSettings
|
from da.dispersal import Dispersal, EncodedData, DispersalSettings
|
||||||
from py_ecc.bls import G2ProofOfPossession as bls_pop
|
|
||||||
|
|
||||||
from .verifier import DAVerifier, DABlob
|
from py_ecc.bls import G2ProofOfPossession as bls_pop
|
||||||
|
|
||||||
|
|
||||||
class TestDispersal(TestCase):
|
class TestDispersal(TestCase):
|
||||||
@ -46,7 +45,7 @@ class TestDispersal(TestCase):
|
|||||||
self.assertEqual(certificate.row_commitments, [])
|
self.assertEqual(certificate.row_commitments, [])
|
||||||
self.assertIsNotNone(certificate.aggregated_signatures)
|
self.assertIsNotNone(certificate.aggregated_signatures)
|
||||||
self.assertTrue(
|
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):
|
def test_disperse(self):
|
||||||
@ -64,12 +63,7 @@ class TestDispersal(TestCase):
|
|||||||
|
|
||||||
certificate = self.dispersal.disperse(encoded_data)
|
certificate = self.dispersal.disperse(encoded_data)
|
||||||
self.assertIsNotNone(certificate)
|
self.assertIsNotNone(certificate)
|
||||||
self.assertTrue(
|
self.assertTrue(certificate.verify(self.public_keys)
|
||||||
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.assertEqual(
|
self.assertEqual(
|
||||||
certificate.signers,
|
certificate.signers,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user