2018-11-28 19:49:03 +00:00
|
|
|
# beacon_chain
|
2020-03-14 21:54:45 +00:00
|
|
|
# Copyright (c) 2018-2020 Status Research & Development GmbH
|
2018-11-28 19:49:03 +00:00
|
|
|
# Licensed and distributed under either of
|
2019-11-25 15:30:02 +00:00
|
|
|
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
|
|
|
|
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
|
2018-11-28 19:49:03 +00:00
|
|
|
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
|
|
|
|
|
|
|
# At the time of writing, the exact definitions of what should be used for
|
|
|
|
# cryptography in the spec is in flux, with sizes and test vectors still being
|
|
|
|
# hashed out. This layer helps isolate those chagnes.
|
|
|
|
|
2019-12-10 14:20:40 +00:00
|
|
|
# BLS signatures can be combined such that multiple signatures are aggregated.
|
|
|
|
# Each time a new signature is added, the corresponding public key must be
|
|
|
|
# added to the verification key as well - if a key signs twice, it must be added
|
|
|
|
# twice to the verification key. Aggregated signatures can be combined
|
|
|
|
# arbitrarily (like addition) as long as public keys are aggregated in the same
|
|
|
|
# way.
|
2018-12-27 20:14:37 +00:00
|
|
|
#
|
2019-12-10 14:20:40 +00:00
|
|
|
# In eth2, we use a single bit to record which keys have signed, thus we cannot
|
|
|
|
# combined overlapping aggregates - ie if we have an aggregate of signatures of
|
|
|
|
# A, B and C, and another with B, C and D, we cannot practically combine them
|
|
|
|
# even if in theory it is possible to allow this in BLS.
|
2018-12-27 20:14:37 +00:00
|
|
|
|
2020-04-11 08:51:07 +00:00
|
|
|
{.push raises: [Defect].}
|
|
|
|
|
2018-11-28 19:49:03 +00:00
|
|
|
import
|
2020-07-23 14:38:28 +00:00
|
|
|
# Standard library
|
|
|
|
options, tables,
|
2020-03-04 21:27:11 +00:00
|
|
|
# Internal
|
2020-06-03 13:52:02 +00:00
|
|
|
./digest,
|
2020-03-04 21:27:11 +00:00
|
|
|
# Status
|
2020-04-11 08:51:07 +00:00
|
|
|
stew/[endians2, objects, results, byteutils],
|
|
|
|
blscurve,
|
2020-03-04 21:27:11 +00:00
|
|
|
chronicles,
|
2020-04-11 08:51:07 +00:00
|
|
|
json_serialization,
|
2020-03-04 21:27:11 +00:00
|
|
|
# Standard library
|
|
|
|
hashes
|
2018-12-19 12:58:53 +00:00
|
|
|
|
2020-04-11 08:51:07 +00:00
|
|
|
export results, json_serialization
|
2020-03-04 21:27:11 +00:00
|
|
|
|
|
|
|
# Type definitions
|
|
|
|
# ----------------------------------------------------------------------
|
2018-11-28 19:49:03 +00:00
|
|
|
|
2020-04-11 08:51:07 +00:00
|
|
|
const
|
|
|
|
RawSigSize* = 96
|
|
|
|
RawPubKeySize* = 48
|
2020-08-15 17:33:58 +00:00
|
|
|
# RawPrivKeySize* = 48 for Miracl / 32 for BLST
|
2020-04-11 08:51:07 +00:00
|
|
|
|
2018-11-28 19:49:03 +00:00
|
|
|
type
|
2020-08-04 17:15:13 +00:00
|
|
|
BlsValueType* = enum
|
2019-07-03 07:35:05 +00:00
|
|
|
Real
|
2020-08-04 17:15:13 +00:00
|
|
|
OpaqueBlob
|
2019-07-03 07:35:05 +00:00
|
|
|
|
2020-07-26 08:27:11 +00:00
|
|
|
BlsValue*[N: static int, T: blscurve.PublicKey or blscurve.Signature] = object
|
2020-08-04 17:15:13 +00:00
|
|
|
# TODO This is a temporary type needed until we sort out the
|
|
|
|
# issues with invalid BLS values appearing in the SSZ test suites.
|
|
|
|
case kind*: BlsValueType
|
2019-07-03 07:35:05 +00:00
|
|
|
of Real:
|
2020-08-04 17:15:13 +00:00
|
|
|
blsValue*: T
|
|
|
|
of OpaqueBlob:
|
|
|
|
blob*: array[N, byte]
|
2019-07-03 07:35:05 +00:00
|
|
|
|
2020-04-11 08:51:07 +00:00
|
|
|
ValidatorPubKey* = BlsValue[RawPubKeySize, blscurve.PublicKey]
|
2019-07-03 07:35:05 +00:00
|
|
|
|
2020-04-11 08:51:07 +00:00
|
|
|
ValidatorPrivKey* = distinct blscurve.SecretKey
|
2019-07-03 07:35:05 +00:00
|
|
|
|
2020-04-11 08:51:07 +00:00
|
|
|
ValidatorSig* = BlsValue[RawSigSize, blscurve.Signature]
|
2019-07-03 07:35:05 +00:00
|
|
|
|
2020-04-11 08:51:07 +00:00
|
|
|
BlsCurveType* = ValidatorPrivKey | ValidatorPubKey | ValidatorSig
|
|
|
|
|
|
|
|
BlsResult*[T] = Result[T, cstring]
|
2018-11-29 01:08:34 +00:00
|
|
|
|
2020-06-01 19:48:20 +00:00
|
|
|
RandomSourceDepleted* = object of CatchableError
|
|
|
|
|
2020-06-25 10:23:10 +00:00
|
|
|
TrustedSig* = object
|
|
|
|
data*: array[RawSigSize, byte]
|
|
|
|
|
|
|
|
SomeSig* = TrustedSig | ValidatorSig
|
|
|
|
|
2020-08-15 17:33:58 +00:00
|
|
|
export AggregateSignature
|
|
|
|
|
2020-03-04 21:27:11 +00:00
|
|
|
# API
|
|
|
|
# ----------------------------------------------------------------------
|
2020-09-24 17:04:10 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.3/specs/phase0/beacon-chain.md#bls-signatures
|
2020-03-04 21:27:11 +00:00
|
|
|
|
2020-04-11 08:51:07 +00:00
|
|
|
func toPubKey*(privkey: ValidatorPrivKey): ValidatorPubKey =
|
2020-03-04 21:27:11 +00:00
|
|
|
## Create a private key from a public key
|
|
|
|
# Un-specced in either hash-to-curve or Eth2
|
|
|
|
# TODO: Test suite should use `keyGen` instead
|
2020-08-10 14:51:23 +00:00
|
|
|
ValidatorPubKey(kind: Real, blsValue: SecretKey(privkey).privToPub())
|
2020-03-04 21:27:11 +00:00
|
|
|
|
2020-07-23 14:38:28 +00:00
|
|
|
proc toRealPubKey(pubkey: ValidatorPubKey): Option[ValidatorPubKey] =
|
2020-08-04 18:13:22 +00:00
|
|
|
var validatorKeyCache {.threadvar.}:
|
|
|
|
Table[array[RawPubKeySize, byte], Option[ValidatorPubKey]]
|
2020-07-23 14:38:28 +00:00
|
|
|
|
2020-08-04 17:44:16 +00:00
|
|
|
case pubkey.kind:
|
|
|
|
of Real:
|
2020-07-23 14:38:28 +00:00
|
|
|
return some(pubkey)
|
2020-08-04 17:44:16 +00:00
|
|
|
of OpaqueBlob:
|
2020-08-10 14:51:23 +00:00
|
|
|
validatorKeyCache.withValue(pubkey.blob, key) do:
|
|
|
|
return key[]
|
|
|
|
do:
|
2020-08-04 17:44:16 +00:00
|
|
|
var val: blscurve.PublicKey
|
|
|
|
let maybeRealKey =
|
|
|
|
if fromBytes(val, pubkey.blob):
|
|
|
|
some ValidatorPubKey(kind: Real, blsValue: val)
|
|
|
|
else:
|
|
|
|
none ValidatorPubKey
|
2020-08-10 14:51:23 +00:00
|
|
|
return validatorKeyCache.mGetOrPut(pubkey.blob, maybeRealKey)
|
2020-07-23 14:38:28 +00:00
|
|
|
|
2020-09-01 13:44:40 +00:00
|
|
|
# TODO this needs a massive comment explaining the reasoning along with every
|
|
|
|
# seemingly ad-hoc place where it's called - one shouldn't have to git-blame
|
|
|
|
# commits and PRs for information which ought to be inplace here in the code
|
2020-07-23 18:24:38 +00:00
|
|
|
proc initPubKey*(pubkey: ValidatorPubKey): ValidatorPubKey =
|
|
|
|
let key = toRealPubKey(pubkey)
|
|
|
|
if key.isNone:
|
|
|
|
return ValidatorPubKey()
|
|
|
|
key.get
|
|
|
|
|
2020-08-15 17:33:58 +00:00
|
|
|
func init*(agg: var AggregateSignature, sig: ValidatorSig) {.inline.}=
|
|
|
|
## Initializes an aggregate signature context
|
|
|
|
## This assumes that the signature is valid
|
|
|
|
agg.init(sig.blsValue)
|
|
|
|
|
|
|
|
func aggregate*(agg: var AggregateSignature, sig: ValidatorSig) {.inline.}=
|
|
|
|
## Aggregate two Validator Signatures
|
2020-03-04 21:27:11 +00:00
|
|
|
## This assumes that they are real signatures
|
2020-08-15 17:33:58 +00:00
|
|
|
agg.aggregate(sig.blsValue)
|
|
|
|
|
|
|
|
func finish*(agg: AggregateSignature): ValidatorSig {.inline.}=
|
|
|
|
## Canonicalize an AggregateSignature into a signature
|
|
|
|
result.kind = Real
|
|
|
|
result.blsValue.finish(agg)
|
2020-03-04 21:27:11 +00:00
|
|
|
|
2020-09-24 17:04:10 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.3/specs/phase0/beacon-chain.md#bls-signatures
|
2020-07-23 14:38:28 +00:00
|
|
|
proc blsVerify*(
|
2020-03-04 21:27:11 +00:00
|
|
|
pubkey: ValidatorPubKey, message: openArray[byte],
|
|
|
|
signature: ValidatorSig): bool =
|
|
|
|
## Check that a signature is valid for a message
|
|
|
|
## under the provided public key.
|
|
|
|
## returns `true` if the signature is valid, `false` otherwise.
|
|
|
|
##
|
|
|
|
## The proof-of-possession MUST be verified before calling this function.
|
|
|
|
## It is recommended to use the overload that accepts a proof-of-possession
|
|
|
|
## to enforce correct usage.
|
|
|
|
if signature.kind != Real:
|
2020-08-04 17:15:13 +00:00
|
|
|
# Invalid signatures are possible in deposits (discussed with Danny)
|
2020-03-04 21:27:11 +00:00
|
|
|
return false
|
2020-07-23 14:38:28 +00:00
|
|
|
let realkey = toRealPubKey(pubkey)
|
|
|
|
if realkey.isNone:
|
2020-03-04 21:27:11 +00:00
|
|
|
# TODO: chronicles warning
|
|
|
|
return false
|
2019-07-03 07:35:05 +00:00
|
|
|
|
2020-03-04 21:27:11 +00:00
|
|
|
# TODO: remove fully if the comment below is not true anymore and
|
|
|
|
# and we don't need this workaround
|
|
|
|
# # TODO bls_verify_multiple(...) used to have this workaround, and now it
|
|
|
|
# # lives here. No matter the signature, there's also no meaningful way to
|
|
|
|
# # verify it -- it's a kind of vacuous truth. No pubkey/sig pairs. Sans a
|
|
|
|
# # getBytes() or similar mechanism, pubKey == default(ValidatorPubKey) is
|
|
|
|
# # a way to create many false positive matches. This seems odd.
|
|
|
|
# if pubkey.getBytes() == default(ValidatorPubKey).getBytes():
|
|
|
|
# return true
|
2020-07-23 14:38:28 +00:00
|
|
|
realkey.get.blsValue.verify(message, signature.blsValue)
|
2020-03-04 21:27:11 +00:00
|
|
|
|
2020-06-16 05:45:04 +00:00
|
|
|
func blsSign*(privkey: ValidatorPrivKey, message: openArray[byte]): ValidatorSig =
|
2020-03-04 21:27:11 +00:00
|
|
|
## Computes a signature from a secret key and a message
|
2020-04-11 08:51:07 +00:00
|
|
|
ValidatorSig(kind: Real, blsValue: SecretKey(privkey).sign(message))
|
2020-03-04 21:27:11 +00:00
|
|
|
|
2020-07-23 14:38:28 +00:00
|
|
|
proc blsFastAggregateVerify*(
|
2020-06-16 05:45:04 +00:00
|
|
|
publicKeys: openArray[ValidatorPubKey],
|
|
|
|
message: openArray[byte],
|
2020-03-04 21:27:11 +00:00
|
|
|
signature: ValidatorSig
|
|
|
|
): bool =
|
|
|
|
## Verify the aggregate of multiple signatures on the same message
|
|
|
|
## This function is faster than AggregateVerify
|
|
|
|
##
|
|
|
|
## The proof-of-possession MUST be verified before calling this function.
|
|
|
|
## It is recommended to use the overload that accepts a proof-of-possession
|
|
|
|
## to enforce correct usage.
|
|
|
|
# TODO: Note: `invalid` in the following paragraph means invalid by construction
|
|
|
|
# The keys/signatures are not even points on the elliptic curves.
|
|
|
|
# To respect both the IETF API and the fact that
|
|
|
|
# we can have invalid public keys (as in not point on the elliptic curve),
|
|
|
|
# requiring a wrapper indirection,
|
|
|
|
# we need a first pass to extract keys from the wrapper
|
|
|
|
# and then call fastAggregateVerify.
|
|
|
|
# Instead:
|
|
|
|
# - either we expose a new API: context + init-update-finish
|
|
|
|
# in blscurve which already exists internally
|
|
|
|
# - or at network/databases/serialization boundaries we do not
|
|
|
|
# allow invalid BLS objects to pollute consensus routines
|
|
|
|
if signature.kind != Real:
|
|
|
|
return false
|
|
|
|
var unwrapped: seq[PublicKey]
|
2020-08-04 17:15:13 +00:00
|
|
|
for pubkey in publicKeys:
|
2020-07-23 14:38:28 +00:00
|
|
|
let realkey = toRealPubKey(pubkey)
|
|
|
|
if realkey.isNone:
|
2020-03-04 21:27:11 +00:00
|
|
|
return false
|
2020-07-23 14:38:28 +00:00
|
|
|
unwrapped.add realkey.get.blsValue
|
2020-06-16 05:45:04 +00:00
|
|
|
|
|
|
|
fastAggregateVerify(unwrapped, message, signature.blsValue)
|
2019-09-10 22:03:06 +00:00
|
|
|
|
2020-03-04 21:27:11 +00:00
|
|
|
proc toGaugeValue*(hash: Eth2Digest): int64 =
|
|
|
|
# Only the last 8 bytes are taken into consideration in accordance
|
|
|
|
# to the ETH2 metrics spec:
|
|
|
|
# https://github.com/ethereum/eth2.0-metrics/blob/6a79914cb31f7d54858c7dd57eee75b6162ec737/metrics.md#interop-metrics
|
2020-08-27 06:32:51 +00:00
|
|
|
cast[int64](uint64.fromBytesLE(hash.data.toOpenArray(24, 31)))
|
2020-03-04 21:27:11 +00:00
|
|
|
|
|
|
|
# Codecs
|
|
|
|
# ----------------------------------------------------------------------
|
|
|
|
|
2020-04-11 08:51:07 +00:00
|
|
|
func `$`*(x: ValidatorPrivKey): string =
|
|
|
|
"<private key>"
|
|
|
|
|
2020-03-04 21:27:11 +00:00
|
|
|
func `$`*(x: BlsValue): string =
|
2020-03-11 13:50:08 +00:00
|
|
|
# The prefix must be short
|
|
|
|
# due to the mechanics of the `shortLog` function.
|
2020-08-18 20:29:33 +00:00
|
|
|
case x.kind
|
|
|
|
of Real: x.blsValue.toHex()
|
|
|
|
of OpaqueBlob: "r:" & x.blob.toHex()
|
2020-03-04 21:27:11 +00:00
|
|
|
|
2020-08-15 17:33:58 +00:00
|
|
|
func toRaw*(x: ValidatorPrivKey): array[32, byte] =
|
2020-07-26 08:27:11 +00:00
|
|
|
# TODO: distinct type - see https://github.com/status-im/nim-blscurve/pull/67
|
2020-08-15 17:33:58 +00:00
|
|
|
when BLS_BACKEND == BLST:
|
|
|
|
result = SecretKey(x).exportRaw()
|
|
|
|
else:
|
|
|
|
# Miracl exports to 384-bit arrays, but Curve order is 256-bit
|
|
|
|
let raw = SecretKey(x).exportRaw()
|
|
|
|
result[0..32-1] = raw.toOpenArray(48-32, 48-1)
|
2020-04-11 08:51:07 +00:00
|
|
|
|
|
|
|
func toRaw*(x: BlsValue): auto =
|
2020-03-04 21:27:11 +00:00
|
|
|
if x.kind == Real:
|
|
|
|
x.blsValue.exportRaw()
|
|
|
|
else:
|
|
|
|
x.blob
|
|
|
|
|
2020-06-25 10:23:10 +00:00
|
|
|
func toRaw*(x: TrustedSig): auto =
|
|
|
|
x.data
|
|
|
|
|
2020-04-11 08:51:07 +00:00
|
|
|
func toHex*(x: BlsCurveType): string =
|
|
|
|
toHex(toRaw(x))
|
|
|
|
|
2020-06-16 05:45:04 +00:00
|
|
|
func fromRaw*(T: type ValidatorPrivKey, bytes: openArray[byte]): BlsResult[T] =
|
2020-04-11 08:51:07 +00:00
|
|
|
var val: SecretKey
|
|
|
|
if val.fromBytes(bytes):
|
|
|
|
ok ValidatorPrivKey(val)
|
|
|
|
else:
|
|
|
|
err "bls: invalid private key"
|
|
|
|
|
2020-06-16 05:45:04 +00:00
|
|
|
func fromRaw*[N, T](BT: type BlsValue[N, T], bytes: openArray[byte]): BlsResult[BT] =
|
2019-09-05 14:27:28 +00:00
|
|
|
# This is a workaround, so that we can deserialize the serialization of a
|
|
|
|
# default-initialized BlsValue without raising an exception
|
2020-07-23 18:24:38 +00:00
|
|
|
when defined(ssz_testing) or BT is ValidatorPubKey:
|
2020-04-11 08:51:07 +00:00
|
|
|
ok BT(kind: OpaqueBlob, blob: toArray(N, bytes))
|
2019-07-03 07:35:05 +00:00
|
|
|
else:
|
2020-08-04 17:15:13 +00:00
|
|
|
# Try if valid BLS value
|
|
|
|
var val: T
|
|
|
|
if fromBytes(val, bytes):
|
|
|
|
ok BT(kind: Real, blsValue: val)
|
|
|
|
else:
|
|
|
|
ok BT(kind: OpaqueBlob, blob: toArray(N, bytes))
|
2019-07-03 07:35:05 +00:00
|
|
|
|
2020-04-11 08:51:07 +00:00
|
|
|
func fromHex*(T: type BlsCurveType, hexStr: string): BlsResult[T] {.inline.} =
|
2020-03-04 21:27:11 +00:00
|
|
|
## Initialize a BLSValue from its hex representation
|
2020-04-11 08:51:07 +00:00
|
|
|
try:
|
|
|
|
T.fromRaw(hexStr.hexToSeqByte())
|
|
|
|
except ValueError:
|
|
|
|
err "bls: cannot parse value"
|
2019-10-01 13:44:38 +00:00
|
|
|
|
2020-08-18 20:29:33 +00:00
|
|
|
func `==`*(a, b: BlsValue): bool =
|
|
|
|
# The assumption here is that converting to raw is mostly fast!
|
|
|
|
case a.kind
|
|
|
|
of Real:
|
|
|
|
if a.kind == b.kind:
|
|
|
|
a.blsValue == b.blsValue
|
|
|
|
else:
|
|
|
|
a.toRaw() == b.blob
|
|
|
|
of OpaqueBlob:
|
|
|
|
if a.kind == b.kind:
|
|
|
|
a.blob == b.blob
|
|
|
|
else:
|
|
|
|
a.blob == b.toRaw()
|
|
|
|
|
2020-03-04 21:27:11 +00:00
|
|
|
# Hashing
|
|
|
|
# ----------------------------------------------------------------------
|
|
|
|
|
|
|
|
template hash*(x: BlsCurveType): Hash =
|
|
|
|
# TODO: prevent using secret keys
|
2020-04-11 08:51:07 +00:00
|
|
|
bind toRaw
|
|
|
|
hash(toRaw(x))
|
2020-03-04 21:27:11 +00:00
|
|
|
|
|
|
|
# Serialization
|
|
|
|
# ----------------------------------------------------------------------
|
2018-12-19 12:58:53 +00:00
|
|
|
|
2020-06-15 22:20:31 +00:00
|
|
|
{.pragma: serializationRaises, raises: [SerializationError, IOError, Defect].}
|
|
|
|
|
2020-04-11 08:51:07 +00:00
|
|
|
proc writeValue*(writer: var JsonWriter, value: ValidatorPubKey) {.
|
|
|
|
inline, raises: [IOError, Defect].} =
|
2020-03-12 01:11:48 +00:00
|
|
|
writer.writeValue(value.toHex())
|
2018-12-19 12:58:53 +00:00
|
|
|
|
2020-06-15 22:20:31 +00:00
|
|
|
proc readValue*(reader: var JsonReader, value: var ValidatorPubKey)
|
|
|
|
{.serializationRaises.} =
|
|
|
|
let key = ValidatorPubKey.fromHex(reader.readValue(string))
|
|
|
|
if key.isOk:
|
|
|
|
value = key.get
|
|
|
|
else:
|
|
|
|
# TODO: Can we provide better diagnostic?
|
|
|
|
raiseUnexpectedValue(reader, "Valid hex-encoded public key expected")
|
2018-12-19 12:58:53 +00:00
|
|
|
|
2020-04-11 08:51:07 +00:00
|
|
|
proc writeValue*(writer: var JsonWriter, value: ValidatorSig) {.
|
|
|
|
inline, raises: [IOError, Defect].} =
|
|
|
|
# Workaround: https://github.com/status-im/nim-beacon-chain/issues/374
|
2020-03-12 01:11:48 +00:00
|
|
|
writer.writeValue(value.toHex())
|
2019-08-07 03:09:26 +00:00
|
|
|
|
2020-06-15 22:20:31 +00:00
|
|
|
proc readValue*(reader: var JsonReader, value: var ValidatorSig)
|
|
|
|
{.serializationRaises.} =
|
|
|
|
let sig = ValidatorSig.fromHex(reader.readValue(string))
|
|
|
|
if sig.isOk:
|
|
|
|
value = sig.get
|
|
|
|
else:
|
|
|
|
# TODO: Can we provide better diagnostic?
|
|
|
|
raiseUnexpectedValue(reader, "Valid hex-encoded signature expected")
|
2019-08-07 03:09:26 +00:00
|
|
|
|
2020-04-11 08:51:07 +00:00
|
|
|
proc writeValue*(writer: var JsonWriter, value: ValidatorPrivKey) {.
|
|
|
|
inline, raises: [IOError, Defect].} =
|
2020-03-12 01:11:48 +00:00
|
|
|
writer.writeValue(value.toHex())
|
2019-08-07 03:09:26 +00:00
|
|
|
|
2020-06-15 22:20:31 +00:00
|
|
|
proc readValue*(reader: var JsonReader, value: var ValidatorPrivKey)
|
|
|
|
{.serializationRaises.} =
|
|
|
|
let key = ValidatorPrivKey.fromHex(reader.readValue(string))
|
|
|
|
if key.isOk:
|
|
|
|
value = key.get
|
|
|
|
else:
|
|
|
|
# TODO: Can we provide better diagnostic?
|
|
|
|
raiseUnexpectedValue(reader, "Valid hex-encoded private key expected")
|
2019-11-09 10:46:34 +00:00
|
|
|
|
2020-06-16 05:45:04 +00:00
|
|
|
template fromSszBytes*(T: type BlsValue, bytes: openArray[byte]): auto =
|
2020-04-11 08:51:07 +00:00
|
|
|
let v = fromRaw(T, bytes)
|
|
|
|
if v.isErr:
|
|
|
|
raise newException(MalformedSszError, $v.error)
|
|
|
|
v[]
|
|
|
|
|
|
|
|
# Logging
|
|
|
|
# ----------------------------------------------------------------------
|
|
|
|
|
|
|
|
func shortLog*(x: BlsValue): string =
|
|
|
|
## Logging for wrapped BLS types
|
|
|
|
## that may contain valid or non-validated data
|
|
|
|
# The prefix must be short
|
|
|
|
# due to the mechanics of the `shortLog` function.
|
|
|
|
if x.kind == Real:
|
2020-08-27 06:32:51 +00:00
|
|
|
x.blsValue.exportRaw().toOpenArray(0, 3).toHex()
|
2020-04-11 08:51:07 +00:00
|
|
|
else:
|
2020-08-27 06:32:51 +00:00
|
|
|
"r:" & x.blob.toOpenArray(0, 3).toHex()
|
2020-04-11 08:51:07 +00:00
|
|
|
|
|
|
|
func shortLog*(x: ValidatorPrivKey): string =
|
|
|
|
## Logging for raw unwrapped BLS types
|
2020-07-26 08:27:11 +00:00
|
|
|
"<private key>"
|
2020-03-04 21:27:11 +00:00
|
|
|
|
2020-06-25 10:23:10 +00:00
|
|
|
func shortLog*(x: TrustedSig): string =
|
2020-08-27 06:32:51 +00:00
|
|
|
x.data.toOpenArray(0, 3).toHex()
|
2020-06-25 10:23:10 +00:00
|
|
|
|
2020-03-04 22:13:37 +00:00
|
|
|
# Initialization
|
|
|
|
# ----------------------------------------------------------------------
|
|
|
|
|
2020-04-11 08:51:07 +00:00
|
|
|
# TODO more specific exceptions? don't raise?
|
|
|
|
|
2020-03-04 21:27:11 +00:00
|
|
|
# For confutils
|
2020-04-11 08:51:07 +00:00
|
|
|
func init*(T: typedesc[ValidatorPrivKey], hex: string): T {.noInit, raises: [ValueError, Defect].} =
|
|
|
|
let v = T.fromHex(hex)
|
|
|
|
if v.isErr:
|
|
|
|
raise (ref ValueError)(msg: $v.error)
|
2020-07-21 16:35:43 +00:00
|
|
|
v[]
|
2020-04-11 08:51:07 +00:00
|
|
|
|
2020-03-04 22:13:37 +00:00
|
|
|
# For mainchain monitor
|
2020-04-11 08:51:07 +00:00
|
|
|
func init*(T: typedesc[ValidatorPubKey], data: array[RawPubKeySize, byte]): T {.noInit, raises: [ValueError, Defect].} =
|
|
|
|
let v = T.fromRaw(data)
|
|
|
|
if v.isErr:
|
|
|
|
raise (ref ValueError)(msg: $v.error)
|
2020-07-21 16:35:43 +00:00
|
|
|
v[]
|
2020-03-04 22:41:21 +00:00
|
|
|
|
|
|
|
# For mainchain monitor
|
2020-04-11 08:51:07 +00:00
|
|
|
func init*(T: typedesc[ValidatorSig], data: array[RawSigSize, byte]): T {.noInit, raises: [ValueError, Defect].} =
|
|
|
|
let v = T.fromRaw(data)
|
|
|
|
if v.isErr:
|
|
|
|
raise (ref ValueError)(msg: $v.error)
|
2020-07-21 16:35:43 +00:00
|
|
|
v[]
|
2020-07-17 20:59:50 +00:00
|
|
|
|
|
|
|
proc burnMem*(key: var ValidatorPrivKey) =
|
|
|
|
key = default(ValidatorPrivKey)
|