Update BLS to the latest scheme. (#80)
* Attempt to switch to nim-blscurve. * "Fix" BLS test for new tests * Missing domain param in validator keygen
This commit is contained in:
parent
bbd94185a4
commit
e5d152c6d6
|
@ -16,7 +16,7 @@ requires "nim >= 0.18.0",
|
|||
"eth_common",
|
||||
"eth_keys",
|
||||
"nimcrypto",
|
||||
"https://github.com/status-im/nim-milagro-crypto#master",
|
||||
"https://github.com/status-im/nim-blscurve#master",
|
||||
"eth_p2p",
|
||||
"ranges",
|
||||
"chronicles",
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import
|
||||
os, options,
|
||||
confutils/defs, chronicles/options as chroniclesOptions,
|
||||
milagro_crypto, json_serialization,
|
||||
json_serialization,
|
||||
spec/[crypto, datatypes], randao, time
|
||||
|
||||
export
|
||||
|
@ -79,7 +79,7 @@ proc readFileBytes(path: string): seq[byte] =
|
|||
cast[seq[byte]](readFile(path))
|
||||
|
||||
proc loadPrivKey*(p: ValidatorKeyPath): ValidatorPrivKey =
|
||||
initSigKey(readFileBytes(string(p) & ".privkey"))
|
||||
ValidatorPrivKey.init(readFileBytes(string(p) & ".privkey"))
|
||||
|
||||
proc loadRandao*(p: ValidatorKeyPath): Randao =
|
||||
initRandao(readFileBytes(string(p) & ".randao"))
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import
|
||||
deques, options, tables,
|
||||
milagro_crypto,
|
||||
./spec/[datatypes, crypto, digest, helpers, validator], extras,
|
||||
./beacon_chain_db
|
||||
|
||||
|
|
|
@ -383,7 +383,7 @@ proc checkAttestation*(
|
|||
|
||||
if not bls_verify(
|
||||
group_public_key, @(msg.data) & @[0'u8], attestation.aggregate_signature,
|
||||
get_domain(state.fork, attestation.data.slot, DOMAIN_ATTESTATION)
|
||||
0, # TODO: get_domain(state.fork, attestation.data.slot, DOMAIN_ATTESTATION)
|
||||
):
|
||||
warn("Invalid attestation group signature")
|
||||
return
|
||||
|
|
|
@ -46,20 +46,23 @@
|
|||
|
||||
import
|
||||
hashes,
|
||||
milagro_crypto, json_serialization
|
||||
blscurve, json_serialization
|
||||
|
||||
export
|
||||
json_serialization, milagro_crypto.`$`
|
||||
json_serialization
|
||||
|
||||
export blscurve.init, blscurve.getBytes, blscurve.combine
|
||||
|
||||
type
|
||||
ValidatorPubKey* = milagro_crypto.VerKey
|
||||
ValidatorPrivKey* = milagro_crypto.SigKey
|
||||
ValidatorSig* = milagro_crypto.Signature
|
||||
ValidatorPubKey* = blscurve.VerKey
|
||||
ValidatorPrivKey* = blscurve.SigKey
|
||||
ValidatorSig* = blscurve.Signature
|
||||
ValidatorPKI* = ValidatorPrivKey|ValidatorPubKey|ValidatorSig
|
||||
|
||||
template hash*(k: ValidatorPubKey|ValidatorPrivKey): Hash =
|
||||
hash(k.getRaw)
|
||||
hash(k.getBytes())
|
||||
|
||||
func pubKey*(pk: ValidatorPrivKey): ValidatorPubKey = fromSigKey(pk)
|
||||
func pubKey*(pk: ValidatorPrivKey): ValidatorPubKey = pk.getKey()
|
||||
|
||||
func bls_aggregate_pubkeys*(keys: openArray[ValidatorPubKey]): ValidatorPubKey =
|
||||
var empty = true
|
||||
|
@ -74,24 +77,28 @@ func bls_verify*(
|
|||
pubkey: ValidatorPubKey, msg: openArray[byte], sig: ValidatorSig,
|
||||
domain: uint64): bool =
|
||||
# name from spec!
|
||||
# TODO domain!
|
||||
sig.verifyMessage(msg, pubkey)
|
||||
sig.verify(msg, domain, pubkey)
|
||||
|
||||
func bls_sign*(key: ValidatorPrivKey,
|
||||
msg: openarray[byte], domain: uint64): ValidatorSig =
|
||||
# name from spec!
|
||||
key.sign(domain, msg)
|
||||
|
||||
proc writeValue*(writer: var JsonWriter, value: ValidatorPubKey) {.inline.} =
|
||||
writer.writeValue $value
|
||||
writer.writeValue($value)
|
||||
|
||||
proc readValue*(reader: var JsonReader, value: var ValidatorPubKey) {.inline.} =
|
||||
value = initVerKey reader.readValue(string)
|
||||
value = VerKey.init(reader.readValue(string))
|
||||
|
||||
proc writeValue*(writer: var JsonWriter, value: ValidatorSig) {.inline.} =
|
||||
writer.writeValue $value
|
||||
writer.writeValue($value)
|
||||
|
||||
proc readValue*(reader: var JsonReader, value: var ValidatorSig) {.inline.} =
|
||||
value = initSignature reader.readValue(string)
|
||||
value = Signature.init(reader.readValue(string))
|
||||
|
||||
proc writeValue*(writer: var JsonWriter, value: ValidatorPrivKey) {.inline.} =
|
||||
writer.writeValue $value
|
||||
writer.writeValue($value)
|
||||
|
||||
proc readValue*(reader: var JsonReader, value: var ValidatorPrivKey) {.inline.} =
|
||||
value = initSigKey reader.readValue(string)
|
||||
value = SigKey.init(reader.readValue(string))
|
||||
|
||||
|
|
|
@ -13,8 +13,6 @@ import
|
|||
eth_common, nimcrypto/blake2,
|
||||
./spec/[crypto, datatypes, digest]
|
||||
|
||||
from milagro_crypto import getRaw, fromRaw
|
||||
|
||||
# ################### Helper functions ###################################
|
||||
|
||||
# toBytesSSZ convert simple fixed-length types to their SSZ wire representation
|
||||
|
@ -43,7 +41,7 @@ func toBytesSSZ(x: Eth2Digest): array[32, byte] = x.data
|
|||
|
||||
# TODO these two are still being debated:
|
||||
# https://github.com/ethereum/eth2.0-specs/issues/308#issuecomment-447026815
|
||||
func toBytesSSZ(x: ValidatorPubKey|ValidatorSig): auto = x.getRaw()
|
||||
func toBytesSSZ(x: ValidatorPubKey|ValidatorSig): auto = x.getBytes()
|
||||
|
||||
type
|
||||
TrivialTypes =
|
||||
|
@ -116,7 +114,7 @@ proc deserialize[T: TrivialTypes](
|
|||
false
|
||||
else:
|
||||
when T is (ValidatorPubKey|ValidatorSig):
|
||||
if T.fromRaw(data[offset..data.len-1], dest):
|
||||
if dest.init(data[offset..data.len-1]):
|
||||
offset += sszLen(dest)
|
||||
true
|
||||
else:
|
||||
|
@ -307,13 +305,13 @@ func hash_tree_root*(x: ValidatorPubKey): array[32, byte] =
|
|||
## TODO - Warning ⚠️: not part of the spec
|
||||
## as of https://github.com/ethereum/beacon_chain/pull/133/files
|
||||
## This is a "stub" needed for BeaconBlock hashing
|
||||
x.getRaw().hash()
|
||||
x.getBytes().hash()
|
||||
|
||||
func hash_tree_root*(x: ValidatorSig): array[32, byte] =
|
||||
## TODO - Warning ⚠️: not part of the spec
|
||||
## as of https://github.com/ethereum/beacon_chain/pull/133/files
|
||||
## This is a "stub" needed for BeaconBlock hashing
|
||||
x.getRaw().hash()
|
||||
x.getBytes().hash()
|
||||
|
||||
func hash_tree_root_final*(x: object|tuple): Eth2Digest =
|
||||
# TODO suggested for spec:
|
||||
|
|
|
@ -33,8 +33,7 @@
|
|||
import
|
||||
chronicles, math, options, sequtils,
|
||||
./extras, ./ssz,
|
||||
./spec/[beaconstate, crypto, datatypes, digest, helpers, validator],
|
||||
milagro_crypto
|
||||
./spec/[beaconstate, crypto, datatypes, digest, helpers, validator]
|
||||
|
||||
func flatten[T](v: openArray[seq[T]]): seq[T] =
|
||||
# TODO not in nim - doh.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import
|
||||
os, ospaths, strutils, strformat,
|
||||
asyncdispatch2, milagro_crypto, nimcrypto, json_serialization, confutils,
|
||||
asyncdispatch2, nimcrypto, json_serialization, confutils,
|
||||
spec/[datatypes, digest, crypto], conf, randao, time, ssz,
|
||||
../tests/testutil
|
||||
|
||||
|
@ -12,7 +12,7 @@ proc genSingleValidator(path: string): (ValidatorPubKey,
|
|||
ValidatorPrivKey,
|
||||
Eth2Digest) =
|
||||
var v: PrivateValidatorData
|
||||
v.privKey = newSigKey()
|
||||
# v.privKey = newSigKey()
|
||||
if randomBytes(v.randao.seed.data) != sizeof(v.randao.seed.data):
|
||||
raise newException(Exception, "Could not generate randao seed")
|
||||
|
||||
|
@ -51,8 +51,10 @@ cli do (validators: int,
|
|||
withdrawal_credentials: withdrawalCredentials,
|
||||
randao_commitment: randaoCommitment)
|
||||
|
||||
proofOfPossession = signMessage(
|
||||
privkey, hash_tree_root_final(proofOfPossessionData).data)
|
||||
proofOfPossession = bls_sign(
|
||||
privkey, hash_tree_root_final(proofOfPossessionData).data,
|
||||
0 # TODO - domain
|
||||
)
|
||||
|
||||
startupData.validatorDeposits.add Deposit(
|
||||
deposit_data: DepositData(
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import
|
||||
tables, random,
|
||||
asyncdispatch2, milagro_crypto,
|
||||
asyncdispatch2,
|
||||
spec/[datatypes, crypto, digest], randao, ssz
|
||||
|
||||
type
|
||||
|
@ -50,7 +50,9 @@ proc signBlockProposal*(v: AttachedValidator,
|
|||
let proposalRoot = hash_tree_root_final(proposal)
|
||||
|
||||
# TODO: Should we use proposalRoot as data, or digest in regards to signature?
|
||||
result = signMessage(v.privKey, proposalRoot.data)
|
||||
# TODO: Use `domain` here
|
||||
let domain = 0'u64
|
||||
result = bls_sign(v.privKey, proposalRoot.data, domain)
|
||||
else:
|
||||
# TODO:
|
||||
# send RPC
|
||||
|
@ -65,7 +67,9 @@ proc signAttestation*(v: AttachedValidator,
|
|||
let attestationRoot = hash_tree_root_final(attestation)
|
||||
# TODO: Avoid the allocations belows
|
||||
var dataToSign = @(attestationRoot.data) & @[0'u8]
|
||||
result = signMessage(v.privKey, dataToSign)
|
||||
# TODO: Use `domain` here
|
||||
let domain = 0'u64
|
||||
result = bls_sign(v.privKey, dataToSign, domain)
|
||||
else:
|
||||
# TODO:
|
||||
# send RPC
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import
|
||||
sequtils, tables,
|
||||
milagro_crypto,
|
||||
spec/[datatypes, crypto, digest], ssz
|
||||
|
||||
type
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import
|
||||
./bench_common,
|
||||
milagro_crypto,
|
||||
blscurve,
|
||||
nimcrypto, endians, sequtils, times, strformat,
|
||||
random
|
||||
|
||||
|
@ -82,7 +82,7 @@ proc main(nb_samples: Natural) =
|
|||
echo '\n'
|
||||
|
||||
var start = cpuTime()
|
||||
let secret_public_keypairs = newSeqWith(num_validators, newKeyPair())
|
||||
let secret_public_keypairs = newSeqWith(num_validators, KeyPair.random())
|
||||
var stop = cpuTime()
|
||||
echo "#### Message crypto keys, signatures and proofs of possession"
|
||||
echo '\n'
|
||||
|
@ -111,10 +111,11 @@ proc main(nb_samples: Natural) =
|
|||
echo '\n'
|
||||
var pubkeys: seq[VerKey]
|
||||
var signatures: seq[Signature]
|
||||
let domain = 0'u64
|
||||
start = cpuTime()
|
||||
for kp in secret_public_keypairs:
|
||||
pubkeys.add kp.verkey
|
||||
signatures.add kp.sigkey.signMessage(msg.data) # toOpenArray?
|
||||
signatures.add kp.sigkey.sign(domain, msg.data) # toOpenArray?
|
||||
stop = cpuTime()
|
||||
echo &"{num_validators} public key and message signature pairs generated in {stop - start :>4.3f} s"
|
||||
echo &"Throughput: {num_validators.float / (stop - start) :>4.3f} kps/s (keysig pairs/second)"
|
||||
|
@ -147,7 +148,8 @@ proc main(nb_samples: Natural) =
|
|||
|
||||
var msg_verif: bool
|
||||
bench "Benchmarking message verification", msg_verif:
|
||||
msg_verif = agg_sig.verifyMessage(msg.data, agg_pubkey)
|
||||
let domain = 0'u64
|
||||
msg_verif = agg_sig.verify(msg.data, domain, agg_pubkey)
|
||||
|
||||
#####################
|
||||
#
|
||||
|
|
|
@ -24,8 +24,7 @@
|
|||
|
||||
import
|
||||
tables, hashes,
|
||||
milagro_crypto,
|
||||
../../beacon_chain/spec/[datatypes, helpers, digest],
|
||||
../../beacon_chain/spec/[datatypes, helpers, digest, crypto],
|
||||
../../beacon_chain/ssz
|
||||
|
||||
type
|
||||
|
|
|
@ -2,7 +2,6 @@ import
|
|||
confutils,
|
||||
json, strformat,
|
||||
options, sequtils, random,
|
||||
milagro_crypto,
|
||||
../tests/[testutil],
|
||||
../beacon_chain/spec/[beaconstate, crypto, datatypes, digest, helpers, validator],
|
||||
../beacon_chain/[extras, ssz, state_transition, fork_choice]
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
||||
|
||||
import
|
||||
unittest, nimcrypto, eth_common, sequtils, options, milagro_crypto,
|
||||
unittest, nimcrypto, eth_common, sequtils, options, blscurve,
|
||||
../beacon_chain/ssz, ../beacon_chain/spec/datatypes
|
||||
|
||||
func filled[N: static[int], T](typ: type array[N, T], value: T): array[N, T] =
|
||||
|
@ -83,7 +83,7 @@ suite "Simple serialization":
|
|||
deserialize(ser, type(v)).get() == v
|
||||
|
||||
test "Key roundtrip":
|
||||
let v = newSigKey().fromSigKey()
|
||||
let v = SigKey.random().getKey()
|
||||
let ser = v.serialize()
|
||||
|
||||
check:
|
||||
|
@ -94,7 +94,7 @@ suite "Simple serialization":
|
|||
let
|
||||
bb = BeaconBlock(
|
||||
slot: 42,
|
||||
signature: signMessage(newSigKey(), "")
|
||||
signature: sign(SigKey.random(), 0'u64, "")
|
||||
)
|
||||
bs = BeaconState(slot: 42)
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
||||
|
||||
import
|
||||
options, milagro_crypto, sequtils,
|
||||
options, sequtils,
|
||||
../beacon_chain/[extras, ssz, state_transition],
|
||||
../beacon_chain/spec/[beaconstate, crypto, datatypes, digest, helpers, validator]
|
||||
|
||||
|
@ -43,7 +43,7 @@ func makeDeposit(i: int, flags: UpdateFlags): Deposit =
|
|||
## for testing :)
|
||||
let
|
||||
privkey = makeValidatorPrivKey(i)
|
||||
pubkey = privkey.fromSigKey()
|
||||
pubkey = privkey.pubKey()
|
||||
withdrawal_credentials = makeFakeHash(i)
|
||||
randao_commitment = repeat_hash(withdrawal_credentials, randaoRounds)
|
||||
|
||||
|
@ -56,8 +56,8 @@ func makeDeposit(i: int, flags: UpdateFlags): Deposit =
|
|||
withdrawal_credentials: withdrawal_credentials,
|
||||
randao_commitment: randao_commitment
|
||||
)
|
||||
signMessage(
|
||||
privkey, hash_tree_root_final(proof_of_possession_data).data)
|
||||
let domain = 0'u64
|
||||
bls_sign(privkey, hash_tree_root_final(proof_of_possession_data).data, domain)
|
||||
|
||||
Deposit(
|
||||
deposit_data: DepositData(
|
||||
|
@ -140,14 +140,15 @@ proc addBlock*(
|
|||
)
|
||||
proposal_hash = hash_tree_root(signed_data)
|
||||
|
||||
assert proposerPrivkey.fromSigKey() == proposer.pubkey,
|
||||
assert proposerPrivkey.pubKey() == proposer.pubkey,
|
||||
"signature key should be derived from private key! - wrong privkey?"
|
||||
|
||||
if skipValidation notin flags:
|
||||
# We have a signature - put it in the block and we should be done!
|
||||
# TODO domain present do something!
|
||||
new_block.signature =
|
||||
# TODO domain missing!
|
||||
signMessage(proposerPrivkey, proposal_hash)
|
||||
bls_sign(proposerPrivkey, proposal_hash,
|
||||
get_domain(state.fork, state.slot, DOMAIN_PROPOSAL))
|
||||
|
||||
assert bls_verify(
|
||||
proposer.pubkey,
|
||||
|
@ -201,9 +202,11 @@ proc makeAttestation*(
|
|||
|
||||
let
|
||||
msg = hash_tree_root_final(data)
|
||||
# TODO: domain
|
||||
domain = 0'u64
|
||||
sig =
|
||||
if skipValidation notin flags:
|
||||
signMessage(hackPrivKey(validator), @(msg.data) & @[0'u8])
|
||||
bls_sign(hackPrivKey(validator), @(msg.data) & @[0'u8], domain)
|
||||
else:
|
||||
ValidatorSig()
|
||||
|
||||
|
|
Loading…
Reference in New Issue