add test for shuffled attestation signatures (#6459)

Followup of #3212 to test proper signature verification. Also document
possible further optimization based on blst `v0.3.13`.
This commit is contained in:
Etan Kissling 2024-07-27 01:31:05 +02:00 committed by GitHub
parent c373e3ab35
commit ea16edd886
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 27 additions and 22 deletions

View File

@ -208,16 +208,6 @@ proc complete(batchCrypto: var BatchCrypto, batch: var Batch, ok: bool) =
reset(batchCrypto.counts)
func combine(a: var Signature, b: Signature) =
var tmp = AggregateSignature.init(CookedSig(a))
tmp.aggregate(b)
a = Signature(tmp.finish())
func combine(a: var PublicKey, b: PublicKey) =
var tmp = AggregatePublicKey.init(CookedPubKey(a))
tmp.aggregate(b)
a = PublicKey(tmp.finish())
proc batchVerifyTask(task: ptr BatchTask) {.nimcall.} =
# Task suitable for running in taskpools - look, no GC!
let
@ -366,18 +356,11 @@ proc verifySoon(
batch = batchCrypto[].getBatch()
fut = newFuture[BatchResult](name)
var found = false
# Find existing signature sets with the same message - if we can verify an
# aggregate instead of several signatures, that is _much_ faster
for item in batch[].sigsets.mitems():
if item.message == sigset.message:
item.signature.combine(sigset.signature)
item.pubkey.combine(sigset.pubkey)
found = true
break
if not found:
batch[].sigsets.add sigset
# TODO If there is a signature set `item in batch[].sigsets.mitems()`
# with `item.message == sigset.message`, further performance could be gained
# by implementing Pippenger multi-scalar multiplication in `nim-blscurve`.
# https://gist.github.com/wemeetagain/d52fc4b077f80db6e423935244c2afb2
batch[].sigsets.add sigset
# We need to keep the "original" sigset to allow verifying each signature
# one by one in the case the combined operation fails

View File

@ -181,6 +181,28 @@ suite "Gossip validation " & preset():
fut_1_0.waitFor().error()[0] == ValidationResult.Reject
fut_1_1.waitFor().isOk()
block:
pool[].nextAttestationEpoch.setLen(0) # reset for test
check:
att_1_0.data == att_1_1.data
beacon_committee[0] != beacon_committee[1] # Different validator
var
broken_1_0 = att_1_0
broken_1_1 = att_1_1
broken_1_0.signature = att_1_1.signature
broken_1_1.signature = att_1_0.signature
# The signatures were swapped and no longer match their pubkeys;
# the individual attestations are invalid but their aggregate validates!
let
fut_1_0 = validateAttestation(
pool, batchCrypto, broken_1_0, beaconTime, subnet, true)
fut_1_1 = validateAttestation(
pool, batchCrypto, broken_1_1, beaconTime, subnet, true)
check:
fut_1_0.waitFor().error()[0] == ValidationResult.Reject
fut_1_1.waitFor().error()[0] == ValidationResult.Reject
suite "Gossip validation - Altair":
let cfg = block:
var res = defaultRuntimeConfig