mirror of https://github.com/status-im/nim-eth.git
keys: get rid of deprecated calls (#213)
This commit is contained in:
parent
42b36d1aef
commit
ac5bbe4d3d
|
@ -177,7 +177,7 @@ proc encryptKey(seckey: PrivateKey,
|
|||
if cryptkind == AES128CTR:
|
||||
var ctx: CTR[aes128]
|
||||
ctx.init(toOpenArray(key, 0, 15), iv)
|
||||
ctx.encrypt(seckey.data, crypttext)
|
||||
ctx.encrypt(seckey.toRaw(), crypttext)
|
||||
ctx.clear()
|
||||
result = Success
|
||||
else:
|
||||
|
@ -308,7 +308,7 @@ proc createKeyFileJson*(seckey: PrivateKey,
|
|||
|
||||
outjson = %*
|
||||
{
|
||||
"address": seckey.getPublicKey().toAddress(false),
|
||||
"address": seckey.toPublicKey().tryGet().toAddress(false),
|
||||
"crypto": {
|
||||
"cipher": $cryptkind,
|
||||
"cipherparams": {
|
||||
|
@ -394,7 +394,7 @@ proc decodeKeyFileJson*(j: JsonNode,
|
|||
if res != Success:
|
||||
return res
|
||||
try:
|
||||
seckey = initPrivateKey(plaintext)
|
||||
seckey = PrivateKey.fromRaw(plaintext).tryGet()
|
||||
except CatchableError:
|
||||
return IncorrectPrivateKey
|
||||
result = Success
|
||||
|
|
305
eth/keys.nim
305
eth/keys.nim
|
@ -29,6 +29,8 @@ const
|
|||
## Size of uncompressed public key without format marker (0x04)
|
||||
RawSignatureSize* = SkRawRecoverableSignatureSize
|
||||
|
||||
RawSignatureNRSize* = SkRawSignatureSize
|
||||
|
||||
type
|
||||
PrivateKey* = distinct SkSecretKey
|
||||
|
||||
|
@ -61,6 +63,8 @@ proc toRaw*(seckey: PrivateKey): array[SkRawSecretKeySize, byte] {.borrow.}
|
|||
proc toPublicKey*(seckey: PrivateKey): SkResult[PublicKey] =
|
||||
SkSecretKey(seckey).toPublicKey().mapConvert(PublicKey)
|
||||
|
||||
proc verify*(seckey: PrivateKey): bool {.borrow.}
|
||||
|
||||
proc fromRaw*(T: type PublicKey, data: openArray[byte]): SkResult[T] =
|
||||
if data.len() == SkRawCompressedPubKeySize:
|
||||
return SkPublicKey.fromRaw(data).mapConvert(PublicKey)
|
||||
|
@ -84,11 +88,16 @@ proc toRaw*(pubkey: PublicKey): array[RawPublicKeySize, byte] =
|
|||
|
||||
proc toRawCompressed*(pubkey: PublicKey): array[33, byte] {.borrow.}
|
||||
|
||||
proc random*(t: type KeyPair): SkResult[KeyPair] =
|
||||
proc random*(T: type KeyPair): SkResult[T] =
|
||||
let tmp = ?SkKeypair.random()
|
||||
ok(KeyPair(seckey: PrivateKey(tmp.seckey), pubkey: PublicKey(tmp.pubkey)))
|
||||
ok(T(seckey: PrivateKey(tmp.seckey), pubkey: PublicKey(tmp.pubkey)))
|
||||
|
||||
proc fromRaw(T: type Signature, data: openArray[byte]): SkResult[T] =
|
||||
proc toKeyPair*(seckey: PrivateKey): SkResult[KeyPair] =
|
||||
let
|
||||
pubkey = seckey.toPublicKey()
|
||||
pubkey and ok(KeyPair(seckey: seckey, pubkey: pubkey[]))
|
||||
|
||||
proc fromRaw*(T: type Signature, data: openArray[byte]): SkResult[T] =
|
||||
SkRecoverableSignature.fromRaw(data).mapConvert(Signature)
|
||||
|
||||
proc fromHex*(T: type Signature, data: string): SkResult[T] =
|
||||
|
@ -96,6 +105,11 @@ proc fromHex*(T: type Signature, data: string): SkResult[T] =
|
|||
|
||||
proc toRaw*(sig: Signature): array[RawSignatureSize, byte] {.borrow.}
|
||||
|
||||
proc fromRaw*(T: type SignatureNR, data: openArray[byte]): SkResult[T] =
|
||||
SkSignature.fromRaw(data).mapConvert(SignatureNR)
|
||||
|
||||
proc toRaw*(sig: SignatureNR): array[RawSignatureNRSize, byte] {.borrow.}
|
||||
|
||||
proc toAddress*(pubkey: PublicKey, with0x = true): string =
|
||||
## Convert public key to hexadecimal string address.
|
||||
var hash = keccak256.digest(pubkey.toRaw())
|
||||
|
@ -180,272 +194,39 @@ proc clear*(v: var KeyPair) =
|
|||
proc clear*(v: var SharedSecret) = burnMem(v.data)
|
||||
proc clear*(v: var SharedSecretFull) = burnMem(v.data)
|
||||
|
||||
proc sign*(seckey: PrivateKey, msg: SkMessage): SkResult[Signature] =
|
||||
signRecoverable(SkSecretKey(seckey), msg).mapConvert(Signature)
|
||||
|
||||
# Backwards compat - the functions in here are deprecated and should be moved
|
||||
# reimplemented using functions that return Result instead!
|
||||
proc sign*(seckey: PrivateKey, msg: openArray[byte]): SkResult[Signature] =
|
||||
let hash = keccak256.digest(msg)
|
||||
sign(seckey, hash)
|
||||
|
||||
{.pop.} # raises
|
||||
proc signNR*(seckey: PrivateKey, msg: SkMessage): SkResult[SignatureNR] =
|
||||
sign(SkSecretKey(seckey), msg).mapConvert(SignatureNR)
|
||||
|
||||
from nimcrypto/utils import stripSpaces
|
||||
proc signNR*(seckey: PrivateKey, msg: openArray[byte]): SkResult[SignatureNR] =
|
||||
let hash = keccak256.digest(msg)
|
||||
signNR(seckey, hash)
|
||||
|
||||
type
|
||||
EthKeysException* {.deprecated.} = object of CatchableError
|
||||
Secp256k1Exception* {.deprecated.} = object of CatchableError
|
||||
proc recover*(sig: Signature, msg: SkMessage): SkResult[PublicKey] =
|
||||
recover(SkRecoverableSignature(sig), msg).mapConvert(PublicKey)
|
||||
|
||||
EthKeysStatus* {.deprecated.} = enum
|
||||
Success
|
||||
Error
|
||||
proc recover*(sig: Signature, msg: openArray[byte]): SkResult[PublicKey] =
|
||||
let hash = keccak256.digest(msg)
|
||||
recover(sig, hash)
|
||||
|
||||
template data*(pubkey: PublicKey): auto =
|
||||
SkPublicKey(pubkey).data
|
||||
proc verify*(sig: SignatureNR, msg: SkMessage, key: PublicKey): bool =
|
||||
verify(SkSignature(sig), msg, SkPublicKey(key))
|
||||
|
||||
template data*(seckey: PrivateKey): auto =
|
||||
SkSecretKey(seckey).data
|
||||
proc verify*(sig: SignatureNR, msg: openArray[byte], key: PublicKey): bool =
|
||||
let hash = keccak256.digest(msg)
|
||||
verify(sig, hash, key)
|
||||
|
||||
template data*(sig: Signature): auto =
|
||||
SkRecoverableSignature(sig).data
|
||||
|
||||
proc isZeroKey*(seckey: PrivateKey): bool {.deprecated.} =
|
||||
## Check if private key `seckey` contains only 0 bytes.
|
||||
# TODO this is a weird check - better would be to check if the key is valid!
|
||||
result = true
|
||||
for i in seckey.data: # constant time, loop all bytes always
|
||||
if i != byte(0):
|
||||
result = false
|
||||
|
||||
proc isZeroKey*(pubkey: PublicKey): bool {.deprecated.} =
|
||||
## Check if public key `pubkey` contains only 0 bytes.
|
||||
# TODO this is a weird check - better would be to check if the key is valid!
|
||||
result = true
|
||||
for i in pubkey.data: # constant time, loop all bytes always
|
||||
if i != byte(0):
|
||||
result = false
|
||||
|
||||
proc newPrivateKey*(): PrivateKey {.deprecated: "random".} =
|
||||
let key = PrivateKey.random()
|
||||
if key.isErr:
|
||||
raise newException(Secp256k1Exception, $key.error)
|
||||
key[]
|
||||
|
||||
proc newKeyPair*(): KeyPair {.deprecated: "random".} =
|
||||
let kp = KeyPair.random()
|
||||
if kp.isErr:
|
||||
raise newException(Secp256k1Exception, $kp.error)
|
||||
kp[]
|
||||
|
||||
proc getPublicKey*(seckey: PrivateKey): PublicKey {.deprecated: "toPublicKey".} =
|
||||
let key = seckey.toPublicKey()
|
||||
if key.isErr:
|
||||
raise newException(Secp256k1Exception, "invalid private key")
|
||||
key[]
|
||||
|
||||
proc ecdhAgree*(
|
||||
seckey: PrivateKey, pubkey: PublicKey,
|
||||
s: var SharedSecret): EthKeysStatus {.deprecated.} =
|
||||
let v = ecdhRaw(
|
||||
proc ecdhRaw*(seckey: PrivateKey, pubkey: PublicKey): SkResult[SharedSecret] =
|
||||
ecdhRaw(
|
||||
SkSecretKey(seckey), SkPublicKey(pubkey)).map proc(v: auto): SharedSecret =
|
||||
copyMem(addr result.data[0], unsafeAddr(v.data[1]), sizeof(result))
|
||||
# Remove first byte!
|
||||
copyMem(addr result.data[0], unsafeAddr(v.data[1]), sizeof(result))
|
||||
|
||||
if v.isOk():
|
||||
s = v[]
|
||||
return Success
|
||||
return Error
|
||||
|
||||
proc getRaw*(
|
||||
pubkey: PublicKey): array[RawPublicKeySize, byte] {.deprecated: "toRaw".} =
|
||||
pubkey.toRaw()
|
||||
|
||||
proc getRawCompressed*(
|
||||
pubkey: PublicKey): array[SkRawCompressedPubKeySize, byte] {.
|
||||
deprecated: "toRawCompressed".} =
|
||||
pubkey.toRawCompressed()
|
||||
|
||||
proc recoverPublicKey*(
|
||||
data: openArray[byte], pubkey: var PublicKey): EthKeysStatus {.
|
||||
deprecated: "fromRaw".} =
|
||||
let v = PublicKey.fromRaw(data)
|
||||
if v.isOk():
|
||||
pubkey = v[]
|
||||
return Success
|
||||
|
||||
return Error
|
||||
|
||||
proc signRawMessage*(data: openarray[byte], seckey: PrivateKey,
|
||||
signature: var Signature): EthKeysStatus {.deprecated.} =
|
||||
if len(data) != SkMessageSize:
|
||||
return Error
|
||||
let sig = signRecoverable(
|
||||
SkSecretKey(seckey), SkMessage(data: toArray(32, data.toOpenArray(0, 31))))
|
||||
if sig.isOk():
|
||||
signature = Signature(sig[])
|
||||
return Success
|
||||
|
||||
return Error
|
||||
|
||||
proc signRawMessage*(data: openarray[byte], seckey: PrivateKey,
|
||||
signature: var SignatureNR): EthKeysStatus {.deprecated.} =
|
||||
## Sign message `data` of `KeyLength` size using private key `seckey` and
|
||||
## store result into `signature`.
|
||||
let length = len(data)
|
||||
if length != KeyLength:
|
||||
return(EthKeysStatus.Error)
|
||||
let sig = sign(
|
||||
SkSecretKey(seckey), SkMessage(data: toArray(32, data.toOpenArray(0, 31))))
|
||||
if sig.isOk():
|
||||
signature = SignatureNR(sig[])
|
||||
return Success
|
||||
|
||||
return Error
|
||||
|
||||
proc signMessage*(seckey: PrivateKey,
|
||||
data: openarray[byte]): Signature {.deprecated.} =
|
||||
let hash = keccak256.digest(data)
|
||||
if signRawMessage(hash.data, seckey, result) != EthKeysStatus.Success:
|
||||
raise newException(EthKeysException, "signature failed")
|
||||
|
||||
proc getRaw*(
|
||||
s: SignatureNR): array[SkRawSignatureSize, byte] {.deprecated: "toRaw".} =
|
||||
## Converts signature `s` to serialized form.
|
||||
SkSignature(s).toRaw()
|
||||
|
||||
proc getRaw*(
|
||||
s: Signature): array[SkRawRecoverableSignatureSize, byte] {.
|
||||
deprecated: "toRaw".} =
|
||||
## Converts signature `s` to serialized form.
|
||||
SkRecoverableSignature(s).toRaw()
|
||||
|
||||
proc recoverSignatureKey*(signature: Signature,
|
||||
msg: openarray[byte],
|
||||
pubkey: var PublicKey): EthKeysStatus {.deprecated.} =
|
||||
if len(msg) < SkMessageSize:
|
||||
return Error
|
||||
let pk = recover(
|
||||
SkRecoverableSignature(signature),
|
||||
SkMessage(data: toArray(32, msg.toOpenArray(0, 31))))
|
||||
if pk.isErr(): return Error
|
||||
|
||||
pubkey = PublicKey(pk[])
|
||||
return Success
|
||||
|
||||
proc recoverSignatureKey*(data: openarray[byte],
|
||||
msg: openarray[byte],
|
||||
pubkey: var PublicKey): EthKeysStatus {.deprecated.} =
|
||||
let signature = SkRecoverableSignature.fromRaw(data)
|
||||
if signature.isErr(): return Error
|
||||
|
||||
if len(msg) < SkMessageSize:
|
||||
return Error
|
||||
let pk = recover(
|
||||
SkRecoverableSignature(signature[]),
|
||||
SkMessage(data: toArray(32, msg.toOpenArray(0, 31))))
|
||||
if pk.isErr(): return Error
|
||||
|
||||
pubkey = PublicKey(pk[])
|
||||
return Success
|
||||
|
||||
proc initPrivateKey*(
|
||||
data: openArray[byte]): PrivateKey {.deprecated: "PrivateKey.fromRaw".} =
|
||||
let res = PrivateKey.fromRaw(data)
|
||||
if res.isOk():
|
||||
return res[]
|
||||
|
||||
raise (ref EthKeysException)(msg: $res.error)
|
||||
|
||||
proc initPrivateKey*(
|
||||
data: string): PrivateKey {.deprecated: "PrivateKey.fromHex".} =
|
||||
let res = PrivateKey.fromHex(stripSpaces(data))
|
||||
if res.isOk():
|
||||
return res[]
|
||||
|
||||
raise (ref EthKeysException)(msg: $res.error)
|
||||
|
||||
proc initPublicKey*(
|
||||
hexstr: string): PublicKey {.deprecated: "PublicKey.fromHex".} =
|
||||
let pk = PublicKey.fromHex(stripSpaces(hexstr))
|
||||
if pk.isOk(): return pk[]
|
||||
|
||||
raise newException(EthKeysException, $pk.error)
|
||||
|
||||
proc initPublicKey*(data: openarray[byte]): PublicKey {.deprecated.} =
|
||||
let pk = PublicKey.fromRaw(data)
|
||||
if pk.isOk(): return pk[]
|
||||
|
||||
raise newException(EthKeysException, $pk.error)
|
||||
|
||||
proc signMessage*(seckey: PrivateKey, data: string): Signature {.deprecated.} =
|
||||
signMessage(seckey, cast[seq[byte]](data))
|
||||
|
||||
proc toKeyPair*(key: PrivateKey): KeyPair {.deprecated.} =
|
||||
KeyPair(seckey: key, pubkey: key.getPublicKey())
|
||||
|
||||
proc initSignature*(data: openArray[byte]): Signature {.deprecated.} =
|
||||
let sig = SkRecoverableSignature.fromRaw(data)
|
||||
if sig.isOk(): return Signature(sig[])
|
||||
|
||||
raise newException(EthKeysException, $sig.error)
|
||||
|
||||
proc initSignature*(hexstr: string): Signature {.deprecated.} =
|
||||
let sig = SkRecoverableSignature.fromHex(stripSpaces(hexstr))
|
||||
if sig.isOk(): return Signature(sig[])
|
||||
|
||||
raise newException(EthKeysException, $sig.error)
|
||||
|
||||
proc recoverSignature*(data: openarray[byte],
|
||||
signature: var Signature): EthKeysStatus {.deprecated.} =
|
||||
## Deprecated, use `parseCompact` instead
|
||||
if data.len < RawSignatureSize:
|
||||
return(EthKeysStatus.Error)
|
||||
let sig = SkRecoverableSignature.fromRaw(data)
|
||||
if sig.isErr():
|
||||
return Error
|
||||
signature = Signature(sig[])
|
||||
return Success
|
||||
|
||||
proc recoverKeyFromSignature*(signature: Signature,
|
||||
hash: MDigest[256]): PublicKey {.deprecated.} =
|
||||
## Recover public key from signature `signature` using `message`.
|
||||
let key = recover(SkRecoverableSignature(signature), hash)
|
||||
if key.isOk():
|
||||
return PublicKey(key[])
|
||||
raise newException(EthKeysException, $key.error)
|
||||
|
||||
proc recoverKeyFromSignature*(
|
||||
signature: Signature,
|
||||
message: openArray[byte]): PublicKey {.deprecated.} =
|
||||
let hash = keccak256.digest(message)
|
||||
recoverKeyFromSignature(signature, hash)
|
||||
|
||||
proc recoverKeyFromSignature*(
|
||||
signature: Signature, data: string): PublicKey {.deprecated.} =
|
||||
recoverKeyFromSignature(signature, cast[seq[byte]](data))
|
||||
|
||||
proc parseCompact*(
|
||||
signature: var SignatureNR,
|
||||
data: openarray[byte]): EthKeysStatus {.deprecated.} =
|
||||
let sig = SkSignature.fromRaw(data)
|
||||
if sig.isErr():
|
||||
return Error
|
||||
|
||||
signature = SignatureNR(sig[])
|
||||
return Success
|
||||
|
||||
proc verifySignatureRaw*(
|
||||
signature: SignatureNR, message: openarray[byte],
|
||||
publicKey: PublicKey): EthKeysStatus {.deprecated.} =
|
||||
## Verify `signature` using original `message` (32 bytes) and `publicKey`.
|
||||
if verify(
|
||||
SkSignature(signature),
|
||||
SkMessage(data: toArray(32, message.toOpenArray(0, 31))),
|
||||
SkPublicKey(publicKey)):
|
||||
return Success
|
||||
|
||||
return Error
|
||||
|
||||
proc ecdhAgree*(
|
||||
seckey: PrivateKey, pubkey: PublicKey,
|
||||
s: var SharedSecretFull): EthKeysStatus {.deprecated.} =
|
||||
let v = ecdhRaw(SkSecretKey(seckey), SkPublicKey(pubkey))
|
||||
if v.isOk():
|
||||
s = SharedSecretFull(v[])
|
||||
return Success
|
||||
return Error
|
||||
proc ecdhRawFull*(seckey: PrivateKey, pubkey: PublicKey): SkResult[SharedSecretFull] =
|
||||
ecdhRaw(SkSecretKey(seckey), SkPublicKey(pubkey)).mapconvert(SharedSecretFull)
|
||||
|
|
114
eth/p2p/auth.nim
114
eth/p2p/auth.nim
|
@ -32,14 +32,14 @@ const
|
|||
type
|
||||
Nonce* = array[KeyLength, byte]
|
||||
|
||||
AuthMessageV4* = object {.packed.}
|
||||
AuthMessageV4* {.packed.} = object
|
||||
signature: array[RawSignatureSize, byte]
|
||||
keyhash: array[keccak256.sizeDigest, byte]
|
||||
pubkey: PublicKey
|
||||
pubkey: array[RawPublicKeySize, byte]
|
||||
nonce: array[keccak256.sizeDigest, byte]
|
||||
flag: byte
|
||||
|
||||
AckMessageV4* = object {.packed.}
|
||||
AckMessageV4* {.packed.} = object
|
||||
pubkey: array[RawPublicKeySize, byte]
|
||||
nonce: array[keccak256.sizeDigest, byte]
|
||||
flag: byte
|
||||
|
@ -94,7 +94,7 @@ proc newHandshake*(flags: set[HandshakeFlag] = {Initiator},
|
|||
## Create new `Handshake` object.
|
||||
result.version = byte(version and 0xFF)
|
||||
result.flags = flags
|
||||
result.ephemeral = newKeyPair()
|
||||
result.ephemeral = KeyPair.random().tryGet()
|
||||
if Initiator in flags:
|
||||
result.expectedLength = AckMessageV4Length
|
||||
if randomBytes(result.initiatorNonce) != len(result.initiatorNonce):
|
||||
|
@ -112,25 +112,25 @@ proc authMessagePreEIP8(h: var Handshake,
|
|||
encrypt: bool = true): AuthStatus =
|
||||
## Create plain pre-EIP8 authentication message.
|
||||
var
|
||||
secret: SharedSecret
|
||||
signature: Signature
|
||||
buffer: array[PlainAuthMessageV4Length, byte]
|
||||
flagb: byte
|
||||
header: ptr AuthMessageV4
|
||||
outlen = 0
|
||||
flagb = byte(flag)
|
||||
header = cast[ptr AuthMessageV4](addr buffer[0])
|
||||
if ecdhAgree(h.host.seckey, pubkey, secret) != EthKeysStatus.Success:
|
||||
var secret = ecdhRaw(h.host.seckey, pubkey)
|
||||
if secret.isErr:
|
||||
return(EcdhError)
|
||||
var xornonce = h.initiatorNonce
|
||||
xornonce.sxor(secret.data)
|
||||
if signRawMessage(xornonce, h.ephemeral.seckey,
|
||||
signature) != EthKeysStatus.Success:
|
||||
xornonce.sxor(secret[].data)
|
||||
secret[].clear()
|
||||
let sig = sign(h.ephemeral.seckey, SkMessage(data: xornonce))
|
||||
if sig.isErr:
|
||||
return(SignatureError)
|
||||
h.remoteHPubkey = pubkey
|
||||
header.signature = signature.getRaw()
|
||||
header.keyhash = keccak256.digest(h.ephemeral.pubkey.getRaw()).data
|
||||
header.pubkey = cast[PublicKey](h.host.pubkey.getRaw())
|
||||
header.signature = sig[].toRaw()
|
||||
header.keyhash = keccak256.digest(h.ephemeral.pubkey.toRaw()).data
|
||||
header.pubkey = h.host.pubkey.toRaw()
|
||||
header.nonce = h.initiatorNonce
|
||||
header.flag = flagb
|
||||
if encrypt:
|
||||
|
@ -155,23 +155,23 @@ proc authMessageEIP8(h: var Handshake,
|
|||
encrypt: bool = true): AuthStatus =
|
||||
## Create EIP8 authentication message.
|
||||
var
|
||||
secret: SharedSecret
|
||||
signature: Signature
|
||||
buffer: array[PlainAuthMessageMaxEIP8, byte]
|
||||
padsize: byte
|
||||
|
||||
doAssert(EIP8 in h.flags)
|
||||
outlen = 0
|
||||
if ecdhAgree(h.host.seckey, pubkey, secret) != EthKeysStatus.Success:
|
||||
var secret = ecdhRaw(h.host.seckey, pubkey)
|
||||
if secret.isErr:
|
||||
return(EcdhError)
|
||||
var xornonce = h.initiatorNonce
|
||||
xornonce.sxor(secret.data)
|
||||
if signRawMessage(xornonce, h.ephemeral.seckey,
|
||||
signature) != EthKeysStatus.Success:
|
||||
xornonce.sxor(secret[].data)
|
||||
secret[].clear()
|
||||
var sig = sign(h.ephemeral.seckey, SkMessage(data: xornonce))
|
||||
if sig.isErr:
|
||||
return(SignatureError)
|
||||
h.remoteHPubkey = pubkey
|
||||
var payload = rlp.encodeList(signature.getRaw(),
|
||||
h.host.pubkey.getRaw(),
|
||||
var payload = rlp.encodeList(sig[].toRaw(),
|
||||
h.host.pubkey.toRaw(),
|
||||
h.initiatorNonce,
|
||||
[byte(h.version)])
|
||||
doAssert(len(payload) == PlainAuthMessageEIP8Length)
|
||||
|
@ -216,7 +216,7 @@ proc ackMessagePreEIP8(h: var Handshake,
|
|||
var buffer: array[PlainAckMessageV4Length, byte]
|
||||
outlen = 0
|
||||
var header = cast[ptr AckMessageV4](addr buffer[0])
|
||||
header.pubkey = h.ephemeral.pubkey.getRaw()
|
||||
header.pubkey = h.ephemeral.pubkey.toRaw()
|
||||
header.nonce = h.responderNonce
|
||||
header.flag = byte(flag)
|
||||
if encrypt:
|
||||
|
@ -242,7 +242,7 @@ proc ackMessageEIP8(h: var Handshake,
|
|||
buffer: array[PlainAckMessageMaxEIP8, byte]
|
||||
padsize: byte
|
||||
doAssert(EIP8 in h.flags)
|
||||
var payload = rlp.encodeList(h.ephemeral.pubkey.getRaw(),
|
||||
var payload = rlp.encodeList(h.ephemeral.pubkey.toRaw(),
|
||||
h.responderNonce,
|
||||
[byte(h.version)])
|
||||
doAssert(len(payload) == PlainAckMessageEIP8Length)
|
||||
|
@ -317,32 +317,36 @@ proc ackMessage*(h: var Handshake, output: var openarray[byte],
|
|||
proc decodeAuthMessageV4(h: var Handshake, m: openarray[byte]): AuthStatus =
|
||||
## Decodes V4 AuthMessage.
|
||||
var
|
||||
secret: SharedSecret
|
||||
buffer: array[PlainAuthMessageV4Length, byte]
|
||||
pubkey: PublicKey
|
||||
|
||||
doAssert(Responder in h.flags)
|
||||
if eciesDecrypt(m, buffer, h.host.seckey) != EciesStatus.Success:
|
||||
return(EciesError)
|
||||
var header = cast[ptr AuthMessageV4](addr buffer[0])
|
||||
if recoverPublicKey(header.pubkey.data, pubkey) != EthKeysStatus.Success:
|
||||
let pubkey = PublicKey.fromRaw(header.pubkey)
|
||||
if pubkey.isErr:
|
||||
return(InvalidPubKey)
|
||||
if ecdhAgree(h.host.seckey, pubkey, secret) != EthKeysStatus.Success:
|
||||
var secret = ecdhRaw(h.host.seckey, pubkey[])
|
||||
if secret.isErr:
|
||||
return(EcdhError)
|
||||
var xornonce = header.nonce
|
||||
xornonce.sxor(secret.data)
|
||||
if recoverSignatureKey(header.signature, xornonce,
|
||||
h.remoteEPubkey) != EthKeysStatus.Success:
|
||||
xornonce.sxor(secret[].data)
|
||||
secret[].clear()
|
||||
let sig = Signature.fromRaw(header.signature)
|
||||
if sig.isErr:
|
||||
return(SignatureError)
|
||||
let remoteEPubkey = recover(sig[], SkMessage(data: xornonce))
|
||||
if remoteEPubkey.isErr:
|
||||
return(SignatureError)
|
||||
h.remoteEPubkey = remoteEPubkey[]
|
||||
h.initiatorNonce = header.nonce
|
||||
h.remoteHPubkey = pubkey
|
||||
h.remoteHPubkey = pubkey[]
|
||||
result = Success
|
||||
|
||||
proc decodeAuthMessageEip8(h: var Handshake, m: openarray[byte]): AuthStatus =
|
||||
## Decodes EIP-8 AuthMessage.
|
||||
var
|
||||
pubkey: PublicKey
|
||||
nonce: Nonce
|
||||
secret: SharedSecret
|
||||
|
||||
let size = uint16.fromBytesBE(m)
|
||||
h.expectedLength = int(size) + 2
|
||||
|
@ -368,20 +372,25 @@ proc decodeAuthMessageEip8(h: var Handshake, m: openarray[byte]): AuthStatus =
|
|||
var pubkeyBr = reader.listElem(1).toBytes()
|
||||
var nonceBr = reader.listElem(2).toBytes()
|
||||
var versionBr = reader.listElem(3).toBytes()
|
||||
if recoverPublicKey(pubkeyBr.toOpenArray(),
|
||||
pubkey) != EthKeysStatus.Success:
|
||||
let pubkey = PublicKey.fromRaw(pubkeyBr.toOpenArray())
|
||||
if pubkey.isErr:
|
||||
return(InvalidPubKey)
|
||||
copyMem(addr nonce[0], nonceBr.baseAddr, KeyLength)
|
||||
if ecdhAgree(h.host.seckey, pubkey, secret) != EthKeysStatus.Success:
|
||||
var secret = ecdhRaw(h.host.seckey, pubkey[])
|
||||
if secret.isErr:
|
||||
return(EcdhError)
|
||||
var xornonce = nonce
|
||||
xornonce.sxor(secret.data)
|
||||
if recoverSignatureKey(signatureBr.toOpenArray(),
|
||||
xornonce,
|
||||
h.remoteEPubkey) != EthKeysStatus.Success:
|
||||
xornonce.sxor(secret[].data)
|
||||
secret[].clear()
|
||||
let sig = Signature.fromRaw(signatureBr.toOpenArray())
|
||||
if sig.isErr:
|
||||
return(SignatureError)
|
||||
let remoteEPubkey = recover(sig[], SkMessage(data: xornonce))
|
||||
if remoteEPubkey.isErr:
|
||||
return(SignatureError)
|
||||
h.remoteEPubkey = remoteEPubkey[]
|
||||
h.initiatorNonce = nonce
|
||||
h.remoteHPubkey = pubkey
|
||||
h.remoteHPubkey = pubkey[]
|
||||
h.version = cast[ptr byte](versionBr.baseAddr)[]
|
||||
result = Success
|
||||
except CatchableError:
|
||||
|
@ -411,9 +420,10 @@ proc decodeAckMessageEip8*(h: var Handshake, m: openarray[byte]): AuthStatus =
|
|||
let pubkeyBr = reader.listElem(0).toBytes()
|
||||
let nonceBr = reader.listElem(1).toBytes()
|
||||
let versionBr = reader.listElem(2).toBytes()
|
||||
if recoverPublicKey(pubkeyBr.toOpenArray(),
|
||||
h.remoteEPubkey) != EthKeysStatus.Success:
|
||||
let remoteEPubkey = PublicKey.fromRaw(pubkeyBr.toOpenArray())
|
||||
if remoteEPubkey.isErr:
|
||||
return(InvalidPubKey)
|
||||
h.remoteEPubkey = remoteEPubkey[]
|
||||
copyMem(addr h.responderNonce[0], nonceBr.baseAddr, KeyLength)
|
||||
h.version = cast[ptr byte](versionBr.baseAddr)[]
|
||||
result = Success
|
||||
|
@ -428,8 +438,10 @@ proc decodeAckMessageV4(h: var Handshake, m: openarray[byte]): AuthStatus =
|
|||
if eciesDecrypt(m, buffer, h.host.seckey) != EciesStatus.Success:
|
||||
return(EciesError)
|
||||
var header = cast[ptr AckMessageV4](addr buffer[0])
|
||||
if recoverPublicKey(header.pubkey, h.remoteEPubkey) != EthKeysStatus.Success:
|
||||
let remoteEPubkey = PublicKey.fromRaw(header.pubkey)
|
||||
if remoteEPubkey.isErr:
|
||||
return(InvalidPubKey)
|
||||
h.remoteEPubkey = remoteEPubkey[]
|
||||
h.responderNonce = header.nonce
|
||||
result = Success
|
||||
|
||||
|
@ -479,15 +491,14 @@ proc getSecrets*(h: Handshake, authmsg: openarray[byte],
|
|||
## Derive secrets from handshake `h` using encrypted AuthMessage `authmsg` and
|
||||
## encrypted AckMessage `ackmsg`.
|
||||
var
|
||||
shsec: SharedSecret
|
||||
ctx0: keccak256
|
||||
ctx1: keccak256
|
||||
mac1: MDigest[256]
|
||||
xornonce: Nonce
|
||||
|
||||
# ecdhe-secret = ecdh.agree(ephemeral-privkey, remote-ephemeral-pubk)
|
||||
if ecdhAgree(h.ephemeral.seckey, h.remoteEPubkey,
|
||||
shsec) != EthKeysStatus.Success:
|
||||
var shsec = ecdhRaw(h.ephemeral.seckey, h.remoteEPubkey)
|
||||
if shsec.isErr:
|
||||
return(EcdhError)
|
||||
|
||||
# shared-secret = keccak(ecdhe-secret || keccak(nonce || initiator-nonce))
|
||||
|
@ -497,25 +508,26 @@ proc getSecrets*(h: Handshake, authmsg: openarray[byte],
|
|||
ctx1.update(h.initiatorNonce)
|
||||
mac1 = ctx1.finish()
|
||||
ctx1.clear()
|
||||
ctx0.update(shsec.data)
|
||||
ctx0.update(shsec[].data)
|
||||
ctx0.update(mac1.data)
|
||||
mac1 = ctx0.finish()
|
||||
|
||||
# aes-secret = keccak(ecdhe-secret || shared-secret)
|
||||
ctx0.init()
|
||||
ctx0.update(shsec.data)
|
||||
ctx0.update(shsec[].data)
|
||||
ctx0.update(mac1.data)
|
||||
mac1 = ctx0.finish()
|
||||
|
||||
# mac-secret = keccak(ecdhe-secret || aes-secret)
|
||||
ctx0.init()
|
||||
ctx0.update(shsec.data)
|
||||
ctx0.update(shsec[].data)
|
||||
ctx0.update(mac1.data)
|
||||
secret.aesKey = mac1.data
|
||||
mac1 = ctx0.finish()
|
||||
secret.macKey = mac1.data
|
||||
|
||||
burnMem(shsec)
|
||||
shsec[].clear()
|
||||
|
||||
# egress-mac = keccak256(mac-secret ^ recipient-nonce || auth-sent-init)
|
||||
xornonce = mac1.data
|
||||
xornonce.sxor(h.responderNonce)
|
||||
|
|
|
@ -56,7 +56,7 @@ proc append*(w: var RlpWriter, a: IpAddress) =
|
|||
w.append(a.address_v4.toMemRange)
|
||||
|
||||
proc append(w: var RlpWriter, p: Port) {.inline.} = w.append(p.int)
|
||||
proc append(w: var RlpWriter, pk: PublicKey) {.inline.} = w.append(pk.getRaw())
|
||||
proc append(w: var RlpWriter, pk: PublicKey) {.inline.} = w.append(pk.toRaw())
|
||||
proc append(w: var RlpWriter, h: MDigest[256]) {.inline.} = w.append(h.data)
|
||||
|
||||
proc pack(cmdId: CommandId, payload: BytesRange, pk: PrivateKey): Bytes =
|
||||
|
@ -67,7 +67,7 @@ proc pack(cmdId: CommandId, payload: BytesRange, pk: PrivateKey): Bytes =
|
|||
|
||||
# TODO: There is a lot of unneeded allocations here
|
||||
let encodedData = @[cmdId.byte] & payload.toSeq()
|
||||
let signature = @(pk.signMessage(encodedData).getRaw())
|
||||
let signature = @(pk.sign(encodedData).tryGet().toRaw())
|
||||
let msgHash = keccak256.digest(signature & encodedData)
|
||||
result = @(msgHash.data) & signature & encodedData
|
||||
|
||||
|
@ -77,10 +77,13 @@ proc validateMsgHash(msg: Bytes, msgHash: var MDigest[256]): bool =
|
|||
result = msgHash == keccak256.digest(msg.toOpenArray(MAC_SIZE, msg.high))
|
||||
|
||||
proc recoverMsgPublicKey(msg: Bytes, pk: var PublicKey): bool =
|
||||
msg.len > HEAD_SIZE and
|
||||
recoverSignatureKey(msg.toOpenArray(MAC_SIZE, HEAD_SIZE),
|
||||
keccak256.digest(msg.toOpenArray(HEAD_SIZE, msg.high)).data,
|
||||
pk) == EthKeysStatus.Success
|
||||
if msg.len > HEAD_SIZE:
|
||||
let sig = Signature.fromRaw(msg.toOpenArray(MAC_SIZE, HEAD_SIZE))
|
||||
if sig.isOk():
|
||||
let pubkey = recover(sig[], msg.toOpenArray(HEAD_SIZE, msg.high))
|
||||
if pubkey.isOk():
|
||||
pk = pubkey[]
|
||||
return true
|
||||
|
||||
proc unpack(msg: Bytes): tuple[cmdId: CommandId, payload: Bytes] =
|
||||
# Check against possible RangeError
|
||||
|
@ -154,7 +157,7 @@ proc newDiscoveryProtocol*(privKey: PrivateKey, address: Address,
|
|||
result.address = address
|
||||
result.bootstrapNodes = newSeqOfCap[Node](bootstrapNodes.len)
|
||||
for n in bootstrapNodes: result.bootstrapNodes.add(newNode(n))
|
||||
result.thisNode = newNode(privKey.getPublicKey(), address)
|
||||
result.thisNode = newNode(privKey.toPublicKey().tryGet(), address)
|
||||
result.kademlia = newKademliaProtocol(result.thisNode, result)
|
||||
|
||||
proc recvPing(d: DiscoveryProtocol, node: Node,
|
||||
|
@ -190,12 +193,12 @@ proc recvNeighbours(d: DiscoveryProtocol, node: Node,
|
|||
|
||||
let udpPort = n.listElem(1).toInt(uint16).Port
|
||||
let tcpPort = n.listElem(2).toInt(uint16).Port
|
||||
var pk: PublicKey
|
||||
if recoverPublicKey(n.listElem(3).toBytes.toOpenArray(), pk) != EthKeysStatus.Success:
|
||||
let pk = PublicKey.fromRaw(n.listElem(3).toBytes.toOpenArray())
|
||||
if pk.isErr:
|
||||
warn "Could not parse public key"
|
||||
continue
|
||||
|
||||
neighbours.add(newNode(pk, Address(ip: ip, udpPort: udpPort, tcpPort: tcpPort)))
|
||||
neighbours.add(newNode(pk[], Address(ip: ip, udpPort: udpPort, tcpPort: tcpPort)))
|
||||
d.kademlia.recvNeighbours(node, neighbours)
|
||||
|
||||
proc recvFindNode(d: DiscoveryProtocol, node: Node, payload: Bytes) {.inline, gcsafe.} =
|
||||
|
@ -314,9 +317,10 @@ when isMainModule:
|
|||
let (cmdId, payload) = unpack(m)
|
||||
doAssert(payload == hexToSeqByte"f2cb842edbd4d182944382765da0ab56fb9e64a85a597e6bb27c656b4f1afb7e06b0fd4e41ccde6dba69a3c4a150845aaa4de2")
|
||||
doAssert(cmdId == cmdPong)
|
||||
doAssert(remotePubkey == initPublicKey("78de8a0916848093c73790ead81d1928bec737d565119932b98c6b100d944b7a95e94f847f689fc723399d2e31129d182f7ef3863f2b4c820abbf3ab2722344d"))
|
||||
doAssert(remotePubkey == PublicKey.fromHex(
|
||||
"78de8a0916848093c73790ead81d1928bec737d565119932b98c6b100d944b7a95e94f847f689fc723399d2e31129d182f7ef3863f2b4c820abbf3ab2722344d"))[]
|
||||
|
||||
let privKey = initPrivateKey("a2b50376a79b1a8c8a3296485572bdfbf54708bb46d3c25d73d2723aaaf6a617")
|
||||
let privKey = PrivateKey.fromHex("a2b50376a79b1a8c8a3296485572bdfbf54708bb46d3c25d73d2723aaaf6a617")[]
|
||||
|
||||
# echo privKey
|
||||
|
||||
|
|
|
@ -46,27 +46,33 @@ type
|
|||
PacketError,
|
||||
DecryptError
|
||||
|
||||
proc randomBytes*(v: var openarray[byte]) =
|
||||
if nimcrypto.randomBytes(v) != v.len:
|
||||
proc randomBytes2*(v: var openarray[byte]) =
|
||||
# TODO if this is called randomBytes it breaks calling the real randomBytes
|
||||
# in other modules... sigh, nim modules and global namespaces...
|
||||
# ideally, a new random library will take the place of both these proc's
|
||||
# in as setting without exceptions for such low-level constructs..
|
||||
if randomBytes(v) != v.len:
|
||||
raise newException(RandomSourceDepleted, "Could not randomize bytes")
|
||||
|
||||
proc idNonceHash(nonce, ephkey: openarray[byte]): array[32, byte] =
|
||||
proc idNonceHash(nonce, ephkey: openarray[byte]): MDigest[256] =
|
||||
var ctx: sha256
|
||||
ctx.init()
|
||||
ctx.update(idNoncePrefix)
|
||||
ctx.update(nonce)
|
||||
ctx.update(ephkey)
|
||||
ctx.finish().data
|
||||
ctx.finish()
|
||||
|
||||
proc signIDNonce*(c: Codec, idNonce, ephKey: openarray[byte]): SignatureNR =
|
||||
if signRawMessage(idNonceHash(idNonce, ephKey), c.privKey, result) != EthKeysStatus.Success:
|
||||
raise newException(EthKeysException, "Could not sign idNonce")
|
||||
let sig = signNR(c.privKey, idNonceHash(idNonce, ephKey))
|
||||
if sig.isErr:
|
||||
raise newException(CatchableError, "Could not sign idNonce")
|
||||
sig[]
|
||||
|
||||
proc deriveKeys(n1, n2: NodeID, priv: PrivateKey, pub: PublicKey,
|
||||
idNonce: openarray[byte], result: var HandshakeSecrets) =
|
||||
var eph: SharedSecretFull
|
||||
if ecdhAgree(priv, pub, eph) != EthKeysStatus.Success:
|
||||
raise newException(EthKeysException, "ecdhAgree failed")
|
||||
let eph = ecdhRawFull(priv, pub)
|
||||
if eph.isErr:
|
||||
raise newException(CatchableError, "ecdhRawFull failed")
|
||||
|
||||
# TODO: Unneeded allocation here
|
||||
var info = newSeqOfCap[byte](idNoncePrefix.len + 32 * 2)
|
||||
|
@ -78,7 +84,7 @@ proc deriveKeys(n1, n2: NodeID, priv: PrivateKey, pub: PublicKey,
|
|||
|
||||
static: assert(sizeof(result) == aesKeySize * 3)
|
||||
var res = cast[ptr UncheckedArray[byte]](addr result)
|
||||
hkdf(sha256, eph.data, idNonce, info, toOpenArray(res, 0, sizeof(result) - 1))
|
||||
hkdf(sha256, eph[].data, idNonce, info, toOpenArray(res, 0, sizeof(result) - 1))
|
||||
|
||||
proc encryptGCM*(key, nonce, pt, authData: openarray[byte]): seq[byte] =
|
||||
var ectx: GCM[aes128]
|
||||
|
@ -97,10 +103,10 @@ proc makeAuthHeader(c: Codec, toId: NodeID, nonce: array[gcmNonceSize, byte],
|
|||
if challenge.recordSeq < ln.record.seqNum:
|
||||
resp.record = ln.record
|
||||
|
||||
let ephKey = newPrivateKey()
|
||||
let ephPubkey = ephKey.getPublicKey().getRaw
|
||||
let ephKey = PrivateKey.random().tryGet()
|
||||
let ephPubkey = ephKey.toPublicKey().tryGet().toRaw
|
||||
|
||||
resp.signature = c.signIDNonce(challenge.idNonce, ephPubkey).getRaw
|
||||
resp.signature = c.signIDNonce(challenge.idNonce, ephPubkey).toRaw
|
||||
|
||||
deriveKeys(ln.id, toId, ephKey, challenge.pubKey, challenge.idNonce,
|
||||
handshakeSecrets)
|
||||
|
@ -131,7 +137,7 @@ proc encodeEncrypted*(c: Codec,
|
|||
challenge: Whoareyou):
|
||||
(seq[byte], array[gcmNonceSize, byte]) =
|
||||
var nonce: array[gcmNonceSize, byte]
|
||||
randomBytes(nonce)
|
||||
randomBytes2(nonce)
|
||||
var headEnc: seq[byte]
|
||||
|
||||
var writeKey: AesKey
|
||||
|
@ -223,11 +229,11 @@ proc decodeAuthResp(c: Codec, fromId: NodeId, head: AuthHeader,
|
|||
warn "Unknown auth scheme"
|
||||
return false
|
||||
|
||||
var ephKey: PublicKey
|
||||
if recoverPublicKey(head.ephemeralKey, ephKey) != EthKeysStatus.Success:
|
||||
var ephKey = PublicKey.fromRaw(head.ephemeralKey)
|
||||
if ephKey.isErr:
|
||||
return false
|
||||
|
||||
deriveKeys(fromId, c.localNode.id, c.privKey, ephKey, challenge.idNonce,
|
||||
deriveKeys(fromId, c.localNode.id, c.privKey, ephKey[], challenge.idNonce,
|
||||
secrets)
|
||||
|
||||
var zeroNonce: array[gcmNonceSize, byte]
|
||||
|
|
|
@ -59,10 +59,10 @@ proc makeEnrAux(seqNum: uint64, pk: PrivateKey, pairs: openarray[(string, Field)
|
|||
result.pairs = @pairs
|
||||
result.seqNum = seqNum
|
||||
|
||||
let pubkey = pk.getPublicKey()
|
||||
let pubkey = pk.toPublicKey().tryGet()
|
||||
|
||||
result.pairs.add(("id", Field(kind: kString, str: "v4")))
|
||||
result.pairs.add(("secp256k1", Field(kind: kBytes, bytes: @(pubkey.getRawCompressed()))))
|
||||
result.pairs.add(("secp256k1", Field(kind: kBytes, bytes: @(pubkey.toRawCompressed()))))
|
||||
|
||||
# Sort by key
|
||||
result.pairs.sort() do(a, b: (string, Field)) -> int:
|
||||
|
@ -82,13 +82,13 @@ proc makeEnrAux(seqNum: uint64, pk: PrivateKey, pairs: openarray[(string, Field)
|
|||
var w = initRlpList(result.pairs.len * 2 + 1)
|
||||
w.append(seqNum, result.pairs)
|
||||
|
||||
var sig: SignatureNR
|
||||
if signRawMessage(keccak256.digest(toSign).data, pk, sig) != EthKeysStatus.Success:
|
||||
raise newException(EthKeysException, "Could not sign ENR (internal error)")
|
||||
let sig = signNR(pk, toSign)
|
||||
if sig.isErr:
|
||||
raise newException(CatchableError, "Could not sign ENR (internal error)")
|
||||
|
||||
result.raw = block:
|
||||
var w = initRlpList(result.pairs.len * 2 + 2)
|
||||
w.append(sig.getRaw())
|
||||
w.append(sig[].toRaw())
|
||||
w.append(seqNum, result.pairs)
|
||||
|
||||
macro initRecord*(seqNum: uint64, pk: PrivateKey, pairs: untyped{nkTableConstr}): untyped =
|
||||
|
@ -146,8 +146,10 @@ proc get*(r: Record, key: string, T: type): T =
|
|||
return f.str
|
||||
elif T is PublicKey:
|
||||
requireKind(f, kBytes)
|
||||
if recoverPublicKey(f.bytes, result) != EthKeysStatus.Success:
|
||||
let pk = PublicKey.fromRaw(f.bytes)
|
||||
if pk.isErr:
|
||||
raise newException(ValueError, "Invalid public key")
|
||||
return pk[]
|
||||
elif T is array:
|
||||
when type(result[0]) is byte:
|
||||
requireKind(f, kBytes)
|
||||
|
@ -164,7 +166,10 @@ proc get*(r: Record, key: string, T: type): T =
|
|||
proc get*(r: Record, pubKey: var PublicKey): bool =
|
||||
var pubkeyField: Field
|
||||
if r.getField("secp256k1", pubkeyField) and pubkeyField.kind == kBytes:
|
||||
result = recoverPublicKey(pubkeyField.bytes, pubKey) == EthKeysStatus.Success
|
||||
let pk = PublicKey.fromRaw(pubkeyField.bytes)
|
||||
if pk.isOk:
|
||||
pubKey = pk[]
|
||||
return true
|
||||
|
||||
proc tryGet*(r: Record, key: string, T: type): Option[T] =
|
||||
try:
|
||||
|
@ -194,11 +199,10 @@ proc toTypedRecord*(r: Record): Option[TypedRecord] =
|
|||
proc verifySignatureV4(r: Record, sigData: openarray[byte], content: seq[byte]): bool =
|
||||
var publicKey: PublicKey
|
||||
if r.get(publicKey):
|
||||
var sig: SignatureNR
|
||||
if sig.parseCompact(sigData) == EthKeysStatus.Success:
|
||||
let sig = SignatureNR.fromRaw(sigData)
|
||||
if sig.isOk:
|
||||
var h = keccak256.digest(content)
|
||||
if verifySignatureRaw(sig, h.data, publicKey) == EthKeysStatus.Success:
|
||||
return true
|
||||
return verify(sig[], h, publicKey)
|
||||
|
||||
proc verifySignature(r: Record): bool =
|
||||
var rlp = rlpFromBytes(r.raw.toRange)
|
||||
|
|
|
@ -9,7 +9,7 @@ type
|
|||
record*: Record
|
||||
|
||||
proc toNodeId*(pk: PublicKey): NodeId =
|
||||
readUintBE[256](keccak256.digest(pk.getRaw()).data)
|
||||
readUintBE[256](keccak256.digest(pk.toRaw()).data)
|
||||
|
||||
proc newNode*(enode: ENode): Node =
|
||||
Node(node: enode,
|
||||
|
@ -43,15 +43,15 @@ proc newNode*(r: Record): Node =
|
|||
# Will need some refactor though.
|
||||
discard
|
||||
|
||||
var pk: PublicKey
|
||||
if recoverPublicKey(r.get("secp256k1", seq[byte]), pk) != EthKeysStatus.Success:
|
||||
warn "Could not recover public key"
|
||||
let pk = PublicKey.fromRaw(r.get("secp256k1", seq[byte]))
|
||||
if pk.isErr:
|
||||
warn "Could not recover public key", err = pk.error
|
||||
return
|
||||
|
||||
result = newNode(initENode(pk, a))
|
||||
result = newNode(initENode(pk[], a))
|
||||
result.record = r
|
||||
|
||||
proc hash*(n: Node): hashes.Hash = hash(n.node.pubkey.data)
|
||||
proc hash*(n: Node): hashes.Hash = hash(n.node.pubkey.toRaw)
|
||||
proc `==`*(a, b: Node): bool = (a.isNil and b.isNil) or (not a.isNil and not b.isNil and a.node.pubkey == b.node.pubkey)
|
||||
|
||||
proc address*(n: Node): Address {.inline.} = n.node.address
|
||||
|
|
|
@ -108,7 +108,7 @@ proc decodeWhoAreYou(d: Protocol, msg: Bytes): Whoareyou =
|
|||
proc sendWhoareyou(d: Protocol, address: Address, toNode: NodeId, authTag: AuthTag) =
|
||||
trace "sending who are you", to = $toNode, toAddress = $address
|
||||
let challenge = Whoareyou(authTag: authTag, recordSeq: 0)
|
||||
encoding.randomBytes(challenge.idNonce)
|
||||
encoding.randomBytes2(challenge.idNonce)
|
||||
# If there is already a handshake going on for this nodeid then we drop this
|
||||
# new one. Handshake will get cleaned up after `handshakeTimeout`.
|
||||
# If instead overwriting the handshake would be allowed, the handshake timeout
|
||||
|
@ -181,8 +181,6 @@ proc receive*(d: Protocol, a: Address, msg: Bytes) {.gcsafe,
|
|||
RlpError,
|
||||
IOError,
|
||||
TransportAddressError,
|
||||
EthKeysException,
|
||||
Secp256k1Exception,
|
||||
].} =
|
||||
if msg.len < tagSize: # or magicSize, can be either
|
||||
return # Invalid msg
|
||||
|
@ -482,7 +480,7 @@ proc newProtocol*(privKey: PrivateKey, db: Database,
|
|||
let
|
||||
a = Address(ip: externalIp.get(IPv4_any()),
|
||||
tcpPort: tcpPort, udpPort: udpPort)
|
||||
enode = initENode(privKey.getPublicKey(), a)
|
||||
enode = initENode(privKey.toPublicKey().tryGet(), a)
|
||||
enrRec = enr.Record.init(1, privKey, externalIp, tcpPort, udpPort)
|
||||
node = newNode(enode, enrRec)
|
||||
|
||||
|
|
|
@ -99,7 +99,6 @@ proc eciesEncrypt*(input: openarray[byte], output: var openarray[byte],
|
|||
cipher: CTR[aes128]
|
||||
ctx: HMAC[sha256]
|
||||
iv: array[aes128.sizeBlock, byte]
|
||||
secret: SharedSecret
|
||||
material: array[KeyLength, byte]
|
||||
|
||||
if len(output) < eciesEncryptedLength(len(input)):
|
||||
|
@ -107,12 +106,15 @@ proc eciesEncrypt*(input: openarray[byte], output: var openarray[byte],
|
|||
if randomBytes(iv) != aes128.sizeBlock:
|
||||
return(RandomError)
|
||||
|
||||
var ephemeral = newKeyPair()
|
||||
var ephemeral = KeyPair.random()
|
||||
if ephemeral.isErr:
|
||||
return(RandomError)
|
||||
|
||||
if ecdhAgree(ephemeral.seckey, pubkey, secret) != EthKeysStatus.Success:
|
||||
var secret = ecdhRaw(ephemeral[].seckey, pubkey)
|
||||
if secret.isErr:
|
||||
return(EcdhError)
|
||||
|
||||
material = kdf(secret.data)
|
||||
material = kdf(secret[].data)
|
||||
burnMem(secret)
|
||||
|
||||
copyMem(addr encKey[0], addr material[0], aes128.sizeKey)
|
||||
|
@ -121,7 +123,7 @@ proc eciesEncrypt*(input: openarray[byte], output: var openarray[byte],
|
|||
|
||||
var header = cast[ptr EciesHeader](addr output[0])
|
||||
header.version = 0x04
|
||||
header.pubkey = ephemeral.pubkey.getRaw()
|
||||
header.pubkey = ephemeral[].pubkey.toRaw()
|
||||
header.iv = iv
|
||||
|
||||
var so = eciesDataPos()
|
||||
|
@ -158,11 +160,9 @@ proc eciesDecrypt*(input: openarray[byte],
|
|||
## Length of output data can be calculated using ``eciesDecryptedLength()``
|
||||
## template.
|
||||
var
|
||||
pubkey: PublicKey
|
||||
encKey: array[aes128.sizeKey, byte]
|
||||
cipher: CTR[aes128]
|
||||
ctx: HMAC[sha256]
|
||||
secret: SharedSecret
|
||||
|
||||
if len(input) <= 0:
|
||||
return(IncompleteError)
|
||||
|
@ -174,12 +174,14 @@ proc eciesDecrypt*(input: openarray[byte],
|
|||
return(IncompleteError)
|
||||
if len(input) - eciesOverheadLength() > len(output):
|
||||
return(BufferOverrun)
|
||||
if recoverPublicKey(header.pubkey, pubkey) != EthKeysStatus.Success:
|
||||
let pubkey = PublicKey.fromRaw(header.pubkey)
|
||||
if pubkey.isErr:
|
||||
return(IncorrectKey)
|
||||
if ecdhAgree(seckey, pubkey, secret) != EthKeysStatus.Success:
|
||||
var secret = ecdhRaw(seckey, pubkey[])
|
||||
if secret.isErr:
|
||||
return(EcdhError)
|
||||
|
||||
var material = kdf(secret.data)
|
||||
var material = kdf(secret[].data)
|
||||
burnMem(secret)
|
||||
copyMem(addr encKey[0], addr material[0], aes128.sizeKey)
|
||||
var macKey = sha256.digest(material, ostart = KeyLength div 2)
|
||||
|
|
|
@ -60,7 +60,6 @@ proc initENode*(e: string, node: var ENode): ENodeStatus =
|
|||
uport: int = 0
|
||||
tport: int = 0
|
||||
uri: Uri = initUri()
|
||||
data: string
|
||||
|
||||
if len(e) == 0:
|
||||
return IncorrectUri
|
||||
|
@ -104,13 +103,10 @@ proc initENode*(e: string, node: var ENode): ENodeStatus =
|
|||
else:
|
||||
uport = tport
|
||||
|
||||
try:
|
||||
data = parseHexStr(uri.username)
|
||||
if recoverPublicKey(cast[seq[byte]](data),
|
||||
node.pubkey) != EthKeysStatus.Success:
|
||||
return IncorrectNodeId
|
||||
except CatchableError:
|
||||
let pk = PublicKey.fromHex(uri.username)
|
||||
if pk.isErr:
|
||||
return IncorrectNodeId
|
||||
node.pubkey = pk[]
|
||||
|
||||
try:
|
||||
node.address.ip = parseIpAddress(uri.hostname)
|
||||
|
@ -135,11 +131,8 @@ proc initENode*(pubkey: PublicKey, address: Address): ENode {.inline.} =
|
|||
|
||||
proc isCorrect*(n: ENode): bool =
|
||||
## Returns ``true`` if ENode ``n`` is properly filled.
|
||||
result = false
|
||||
for i in n.pubkey.data:
|
||||
if i != 0x00'u8:
|
||||
result = true
|
||||
break
|
||||
var pk: PublicKey
|
||||
n.pubkey != pk
|
||||
|
||||
proc `$`*(n: ENode): string =
|
||||
## Returns string representation of ENode.
|
||||
|
|
|
@ -51,7 +51,7 @@ const
|
|||
ID_SIZE = 256
|
||||
|
||||
proc toNodeId*(pk: PublicKey): NodeId =
|
||||
readUintBE[256](keccak256.digest(pk.getRaw()).data)
|
||||
readUintBE[256](keccak256.digest(pk.toRaw()).data)
|
||||
|
||||
proc newNode*(pk: PublicKey, address: Address): Node =
|
||||
result.new()
|
||||
|
@ -76,7 +76,7 @@ proc `$`*(n: Node): string =
|
|||
else:
|
||||
"Node[" & $n.node.address.ip & ":" & $n.node.address.udpPort & "]"
|
||||
|
||||
proc hash*(n: Node): hashes.Hash = hash(n.node.pubkey.data)
|
||||
proc hash*(n: Node): hashes.Hash = hash(n.node.pubkey.toRaw)
|
||||
proc `==`*(a, b: Node): bool = (a.isNil and b.isNil) or (not a.isNil and not b.isNil and a.node.pubkey == b.node.pubkey)
|
||||
|
||||
proc newKBucket(istart, iend: NodeId): KBucket =
|
||||
|
@ -259,7 +259,7 @@ template onTimeout(b: untyped) =
|
|||
b
|
||||
|
||||
proc pingId(n: Node, token: seq[byte]): seq[byte] {.inline.} =
|
||||
result = token & @(n.node.pubkey.data)
|
||||
result = token & @(n.node.pubkey.toRaw)
|
||||
|
||||
proc waitPong(k: KademliaProtocol, n: Node, pingid: seq[byte]): Future[bool] =
|
||||
doAssert(pingid notin k.pongFutures, "Already waiting for pong from " & $n)
|
||||
|
@ -441,7 +441,7 @@ proc bootstrap*(k: KademliaProtocol, bootstrapNodes: seq[Node], retries = 0) {.a
|
|||
|
||||
proc recvPong*(k: KademliaProtocol, n: Node, token: seq[byte]) =
|
||||
trace "<<< pong from ", n
|
||||
let pingid = token & @(n.node.pubkey.data)
|
||||
let pingid = token & @(n.node.pubkey.toRaw)
|
||||
var future: Future[bool]
|
||||
if k.pongFutures.take(pingid, future):
|
||||
future.complete(true)
|
||||
|
|
|
@ -162,7 +162,7 @@ template compression(m: MockConf): bool =
|
|||
|
||||
proc newMockPeer*(userConfigurator: proc (m: MockConf)): EthereumNode =
|
||||
var mockConf = new MockConf
|
||||
mockConf.keys = newKeyPair()
|
||||
mockConf.keys = KeyPair.random()[]
|
||||
mockConf.address = localhostAddress(nextUnusedMockPort)
|
||||
inc nextUnusedMockPort
|
||||
mockConf.networkId = 1'u
|
||||
|
|
|
@ -857,8 +857,8 @@ proc disconnect*(peer: Peer, reason: DisconnectionReason, notifyOtherPeer = fals
|
|||
removePeer(peer.network, peer)
|
||||
|
||||
proc validatePubKeyInHello(msg: DevP2P.hello, pubKey: PublicKey): bool =
|
||||
var pk: PublicKey
|
||||
recoverPublicKey(msg.nodeId, pk) == EthKeysStatus.Success and pk == pubKey
|
||||
let pk = PublicKey.fromRaw(msg.nodeId)
|
||||
pk.isOk and pk[] == pubKey
|
||||
|
||||
proc checkUselessPeer(peer: Peer) {.inline.} =
|
||||
if peer.dispatcher.numProtocols == 0:
|
||||
|
@ -1012,7 +1012,7 @@ proc rlpxConnect*(node: EthereumNode, remote: Node): Future[Peer] {.async.} =
|
|||
node.clientId,
|
||||
node.capabilities,
|
||||
uint(node.address.tcpPort),
|
||||
node.keys.pubkey.getRaw())
|
||||
node.keys.pubkey.toRaw())
|
||||
|
||||
var response = await result.handshakeImpl(
|
||||
sendHelloFut,
|
||||
|
@ -1102,7 +1102,7 @@ proc rlpxAccept*(node: EthereumNode,
|
|||
node.clientId,
|
||||
node.capabilities,
|
||||
listenPort.uint,
|
||||
node.keys.pubkey.getRaw())
|
||||
node.keys.pubkey.toRaw())
|
||||
|
||||
var response = await result.handshakeImpl(
|
||||
sendHelloFut,
|
||||
|
|
|
@ -266,11 +266,9 @@ p2pProtocol les(version = lesVersion,
|
|||
if signature.isNone:
|
||||
error "missing announce signature"
|
||||
return
|
||||
let sigHash = keccak256.digest rlp.encodeList(headHash,
|
||||
headNumber,
|
||||
headTotalDifficulty)
|
||||
let signerKey = recoverKeyFromSignature(signature.get.initSignature,
|
||||
sigHash)
|
||||
let sigMsg = rlp.encodeList(headHash, headNumber, headTotalDifficulty)
|
||||
let sig = Signature.fromRaw(signature.get).tryGet()
|
||||
let signerKey = recover(sig, sigMsg).tryGet()
|
||||
if signerKey.toNodeId != peer.remote.id:
|
||||
error "invalid announce signature"
|
||||
# TODO: should we disconnect this peer?
|
||||
|
|
|
@ -297,14 +297,12 @@ proc encode*(self: Payload): Option[Bytes] =
|
|||
plain.add padding
|
||||
|
||||
if self.src.isSome(): # Private key present - signature requested
|
||||
let hash = keccak256.digest(plain)
|
||||
var sig: Signature
|
||||
let err = signRawMessage(hash.data, self.src.get(), sig)
|
||||
if err != EthKeysStatus.Success:
|
||||
notice "Signing message failed", err
|
||||
let sig = sign(self.src.get(), plain)
|
||||
if sig.isErr:
|
||||
notice "Signing message failed", err = sig.error
|
||||
return
|
||||
|
||||
plain.add sig.getRaw()
|
||||
plain.add sig[].toRaw()
|
||||
|
||||
if self.dst.isSome(): # Asymmetric key present - encryption requested
|
||||
var res = newSeq[byte](eciesEncryptedLength(plain.len))
|
||||
|
@ -392,14 +390,13 @@ proc decode*(data: openarray[byte], dst = none[PrivateKey](),
|
|||
debug "Missing expected signature", len = plain.len
|
||||
return
|
||||
|
||||
let sig = plain[^keys.RawSignatureSize .. ^1]
|
||||
let hash = keccak256.digest(plain[0 ..< ^keys.RawSignatureSize])
|
||||
var key: PublicKey
|
||||
let err = recoverSignatureKey(sig, hash.data, key)
|
||||
if err != EthKeysStatus.Success:
|
||||
debug "Failed to recover signature key", err
|
||||
let sig = Signature.fromRaw(plain[^keys.RawSignatureSize .. ^1])
|
||||
let key = sig and recover(
|
||||
sig[], plain.toOpenArray(0, plain.len - keys.RawSignatureSize - 1))
|
||||
if key.isErr:
|
||||
debug "Failed to recover signature key", err = key.error
|
||||
return
|
||||
res.src = some(key)
|
||||
res.src = some(key[])
|
||||
|
||||
if hasSignature:
|
||||
if plain.len > pos + keys.RawSignatureSize:
|
||||
|
@ -633,16 +630,16 @@ proc notify*(filters: var Filters, msg: Message) {.gcsafe.} =
|
|||
if decoded.isNone():
|
||||
continue
|
||||
if filter.privateKey.isSome():
|
||||
keyHash = keccak256.digest(filter.privateKey.get().data)
|
||||
keyHash = keccak256.digest(filter.privateKey.get().toRaw())
|
||||
# TODO: Get rid of the hash and just use pubkey to compare?
|
||||
dst = some(getPublicKey(filter.privateKey.get()))
|
||||
dst = some(toPublicKey(filter.privateKey.get()).tryGet())
|
||||
elif filter.symKey.isSome():
|
||||
keyHash = keccak256.digest(filter.symKey.get())
|
||||
# else:
|
||||
# NOTE: In this case the message was not encrypted
|
||||
else:
|
||||
if filter.privateKey.isSome():
|
||||
if keyHash != keccak256.digest(filter.privateKey.get().data):
|
||||
if keyHash != keccak256.digest(filter.privateKey.get().toRaw()):
|
||||
continue
|
||||
elif filter.symKey.isSome():
|
||||
if keyHash != keccak256.digest(filter.symKey.get()):
|
||||
|
|
|
@ -8,7 +8,7 @@ var targetNode: DiscoveryProtocol
|
|||
init:
|
||||
# Set up a discovery node, this is the node we target when fuzzing
|
||||
var
|
||||
targetNodeKey = initPrivateKey("a2b50376a79b1a8c8a3296485572bdfbf54708bb46d3c25d73d2723aaaf6a617")
|
||||
targetNodeKey = PrivateKey.fromRaw("a2b50376a79b1a8c8a3296485572bdfbf54708bb46d3c25d73d2723aaaf6a617")[]
|
||||
targetNodeAddr = localAddress(DefaultListeningPort)
|
||||
targetNode = newDiscoveryProtocol(targetNodeKey, targetNodeAddr, @[])
|
||||
# Create the transport as else replies on the messages send will fail.
|
||||
|
@ -22,7 +22,7 @@ test:
|
|||
# Sending raw payload is possible but won't find us much. We need a hash and
|
||||
# a signature, and without it there is a big chance it will always result in
|
||||
# "Wrong msg mac from" error.
|
||||
let nodeKey = initPrivateKey("a2b50376a79b1a8c8a3296485572bdfbf54708bb46d3c25d73d2723aaaf6a618")
|
||||
let nodeKey = PrivateKey.fromRaw("a2b50376a79b1a8c8a3296485572bdfbf54708bb46d3c25d73d2723aaaf6a618")[]
|
||||
msg = packData(payload, nodeKey)
|
||||
address = localAddress(DefaultListeningPort + 1)
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ proc generate() =
|
|||
let
|
||||
fromAddr = localAddress(30303)
|
||||
toAddr = localAddress(30304)
|
||||
peerKey = initPrivateKey("a2b50376a79b1a8c8a3296485572bdfbf54708bb46d3c25d73d2723aaaf6a617")
|
||||
peerKey = PrivateKey.fromHex("a2b50376a79b1a8c8a3296485572bdfbf54708bb46d3c25d73d2723aaaf6a617")[]
|
||||
|
||||
# valid data for a Ping packet
|
||||
block:
|
||||
|
@ -42,7 +42,7 @@ proc generate() =
|
|||
# valid data for a FindNode packet
|
||||
block:
|
||||
var data: array[64, byte]
|
||||
data[32 .. ^1] = peerKey.getPublicKey.toNodeId().toByteArrayBE()
|
||||
data[32 .. ^1] = peerKey.toPublicKey().tryGet().toNodeId().toByteArrayBE()
|
||||
let payload = rlp.encode((data, expiration())).toRange
|
||||
let encodedData = @[3.byte] & payload.toSeq()
|
||||
debug "FindNode", data=byteutils.toHex(encodedData)
|
||||
|
@ -54,14 +54,16 @@ proc generate() =
|
|||
let
|
||||
n1Addr = localAddress(30305)
|
||||
n2Addr = localAddress(30306)
|
||||
n1Key = initPrivateKey("a2b50376a79b1a8c8a3296485572bdfbf54708bb46d3c25d73d2723aaaf6a618")
|
||||
n2Key = initPrivateKey("a2b50376a79b1a8c8a3296485572bdfbf54708bb46d3c25d73d2723aaaf6a619")
|
||||
n1Key = PrivateKey.fromHex(
|
||||
"a2b50376a79b1a8c8a3296485572bdfbf54708bb46d3c25d73d2723aaaf6a618")[]
|
||||
n2Key = PrivateKey.fromHex(
|
||||
"a2b50376a79b1a8c8a3296485572bdfbf54708bb46d3c25d73d2723aaaf6a619")[]
|
||||
|
||||
type Neighbour = tuple[ip: IpAddress, udpPort, tcpPort: Port, pk: PublicKey]
|
||||
var nodes = newSeqOfCap[Neighbour](2)
|
||||
|
||||
nodes.add((n1Addr.ip, n1Addr.udpPort, n1Addr.tcpPort, n1Key.getPublicKey()))
|
||||
nodes.add((n2Addr.ip, n2Addr.udpPort, n2Addr.tcpPort, n2Key.getPublicKey()))
|
||||
nodes.add((n1Addr.ip, n1Addr.udpPort, n1Addr.tcpPort, n1Key.toPublicKey().tryGet()))
|
||||
nodes.add((n2Addr.ip, n2Addr.udpPort, n2Addr.tcpPort, n2Key.toPublicKey().tryGet()))
|
||||
|
||||
let payload = rlp.encode((nodes, expiration())).toRange
|
||||
let encodedData = @[4.byte] & payload.toSeq()
|
||||
|
|
|
@ -88,28 +88,28 @@ var jobject: JsonNode
|
|||
suite "KeyFile test suite":
|
||||
test "KeyStoreTests/basic_tests.json test1":
|
||||
var seckey: PrivateKey
|
||||
var expectkey = initPrivateKey(TestVectors[0].getOrDefault("priv").getStr())
|
||||
var expectkey = PrivateKey.fromHex(TestVectors[0].getOrDefault("priv").getStr())[]
|
||||
check:
|
||||
decodeKeyFileJson(TestVectors[0].getOrDefault("keyfile"),
|
||||
TestVectors[0].getOrDefault("password").getStr(),
|
||||
seckey) == KeyFileStatus.Success
|
||||
seckey.data == expectkey.data
|
||||
seckey.toRaw == expectkey.toRaw
|
||||
test "KeyStoreTests/basic_tests.json python_generated_test_with_odd_iv":
|
||||
var seckey: PrivateKey
|
||||
var expectkey = initPrivateKey(TestVectors[1].getOrDefault("priv").getStr())
|
||||
var expectkey = PrivateKey.fromHex(TestVectors[1].getOrDefault("priv").getStr())[]
|
||||
check:
|
||||
decodeKeyFileJson(TestVectors[1].getOrDefault("keyfile"),
|
||||
TestVectors[1].getOrDefault("password").getStr(),
|
||||
seckey) == KeyFileStatus.Success
|
||||
seckey.data == expectkey.data
|
||||
seckey.toRaw == expectkey.toRaw
|
||||
test "KeyStoreTests/basic_tests.json evilnonce":
|
||||
var seckey: PrivateKey
|
||||
var expectkey = initPrivateKey(TestVectors[2].getOrDefault("priv").getStr())
|
||||
var expectkey = PrivateKey.fromHex(TestVectors[2].getOrDefault("priv").getStr())[]
|
||||
check:
|
||||
decodeKeyFileJson(TestVectors[2].getOrDefault("keyfile"),
|
||||
TestVectors[2].getOrDefault("password").getStr(),
|
||||
seckey) == KeyFileStatus.Success
|
||||
seckey.data == expectkey.data
|
||||
seckey.toRaw == expectkey.toRaw
|
||||
test "KeyStoreTests/basic_tests.json evilnonce with wrong password":
|
||||
var seckey: PrivateKey
|
||||
check:
|
||||
|
@ -117,7 +117,7 @@ suite "KeyFile test suite":
|
|||
"wrongpassword",
|
||||
seckey) == KeyFileStatus.IncorrectMac
|
||||
test "Create/Save/Load test":
|
||||
var seckey0 = newPrivateKey()
|
||||
var seckey0 = PrivateKey.random()[]
|
||||
var seckey1: PrivateKey
|
||||
check:
|
||||
createKeyFileJson(seckey0, "randompassword",
|
||||
|
@ -125,7 +125,7 @@ suite "KeyFile test suite":
|
|||
saveKeyFile("test.keyfile", jobject) == KeyFileStatus.Success
|
||||
loadKeyFile("test.keyfile", "randompassword",
|
||||
seckey1) == KeyFileStatus.Success
|
||||
seckey0.data == seckey1.data
|
||||
seckey0.toRaw == seckey1.toRaw
|
||||
removeFile("test.keyfile")
|
||||
test "Load non-existent pathname test":
|
||||
var seckey: PrivateKey
|
||||
|
|
|
@ -17,7 +17,7 @@ suite "Test key and signature data structure":
|
|||
test "Signing from private key object (ported from official eth-keys)":
|
||||
for person in [alice, bob, eve]:
|
||||
let
|
||||
pk = initPrivateKey(person.privkey)
|
||||
pk = PrivateKey.fromHex(person.privkey)[]
|
||||
signature = pk.sign_msg(MSG)
|
||||
|
||||
check: verify_msg(pk.public_key, MSG, signature)
|
||||
|
@ -25,7 +25,7 @@ suite "Test key and signature data structure":
|
|||
test "Hash signing from private key object (ported from official eth-keys)":
|
||||
for person in [alice, bob, eve]:
|
||||
let
|
||||
pk = initPrivateKey(person.privkey)
|
||||
pk = PrivateKey.fromHex(person.privkey)[]
|
||||
signature = pk.sign_msg(MSGHASH)
|
||||
|
||||
check: verify_msg(pk.public_key, MSGHASH, signature)
|
||||
|
@ -33,7 +33,7 @@ suite "Test key and signature data structure":
|
|||
test "Recover public key from message":
|
||||
for person in [alice, bob, eve]:
|
||||
let
|
||||
pk = initPrivateKey(person.privkey)
|
||||
pk = PrivateKey.fromHex(person.privkey)[]
|
||||
signature = pk.sign_msg(MSG)
|
||||
|
||||
recovered_pubkey = recover_pubkey_from_msg(MSG, signature)
|
||||
|
@ -43,7 +43,7 @@ suite "Test key and signature data structure":
|
|||
test "Recover public key from message hash":
|
||||
for person in [alice, bob, eve]:
|
||||
let
|
||||
pk = initPrivateKey(person.privkey)
|
||||
pk = PrivateKey.formHex(person.privkey)[]
|
||||
signature = pk.sign_msg(MSGHASH)
|
||||
|
||||
recovered_pubkey = recover_pubkey_from_msg(MSGHASH, signature)
|
||||
|
@ -53,7 +53,7 @@ suite "Test key and signature data structure":
|
|||
test "Signature serialization and deserialization":
|
||||
for person in [alice, bob, eve]:
|
||||
let
|
||||
pk = initPrivateKey(person.privkey)
|
||||
pk = PrivateKey.fromHex(person.privkey)[]
|
||||
signature = pk.sign_msg(MSG)
|
||||
deserializedSignature = parseSignature(hexToSeqByteBE(person.serialized_sig))
|
||||
|
||||
|
|
|
@ -12,6 +12,8 @@ import eth/keys
|
|||
import nimcrypto/hash, nimcrypto/keccak, nimcrypto/utils
|
||||
from strutils import toLowerAscii
|
||||
|
||||
import stew/byteutils
|
||||
|
||||
proc compare(x: openarray[byte], y: openarray[byte]): bool =
|
||||
result = len(x) == len(y)
|
||||
if result:
|
||||
|
@ -19,9 +21,11 @@ proc compare(x: openarray[byte], y: openarray[byte]): bool =
|
|||
if x[i] != y[i]:
|
||||
result = false
|
||||
break
|
||||
|
||||
let message = "message".toBytes()
|
||||
|
||||
const
|
||||
pkbytes = "58d23b55bc9cdce1f18c2500f40ff4ab7245df9a89505e9b1fa4851f623d241d"
|
||||
message = "message"
|
||||
address = "dc544d1aa88ff8bbd2f2aec754b1f1e99e1812fd"
|
||||
|
||||
alice = [
|
||||
|
@ -49,50 +53,50 @@ const
|
|||
suite "ECC/ECDSA/ECDHE tests suite":
|
||||
test "Known private to known public keys (test data from Ethereum eth-keys)":
|
||||
for person in [alice, bob, eve]:
|
||||
let privkey = initPrivateKey(person[0])
|
||||
var pubkeyHex = $privkey.getPublicKey()
|
||||
let privkey = PrivateKey.fromHex(person[0])[]
|
||||
var pubkeyHex = $privkey.toPublicKey()[]
|
||||
check:
|
||||
pubkeyHex == stripSpaces(person[1])
|
||||
|
||||
test "Recover public key from message":
|
||||
for person in [alice, bob, eve]:
|
||||
let privkey = initPrivateKey(person[0])
|
||||
let signature = privkey.signMessage(message)
|
||||
let recoveredKey = signature.recoverKeyFromSignature(message)
|
||||
let privkey = PrivateKey.fromHex(person[0])[]
|
||||
let signature = privkey.sign(message)[]
|
||||
let recoveredKey = signature.recover(message)[]
|
||||
check:
|
||||
$privkey.getPublicKey() == $recoveredKey
|
||||
$privkey.toPublicKey()[] == $recoveredKey
|
||||
|
||||
test "Signature serialization and deserialization":
|
||||
for person in [alice, bob, eve]:
|
||||
let privkey = initPrivateKey(person[0])
|
||||
let signature = privkey.signMessage(message)
|
||||
let expectSignature = initSignature(person[2])
|
||||
let privkey = PrivateKey.fromHex(person[0])[]
|
||||
let signature = privkey.sign(message)[]
|
||||
let expectSignature = Signature.fromHex(stripSpaces(person[2]))[]
|
||||
check:
|
||||
$signature == $expectSignature
|
||||
|
||||
test "test_recover_from_signature_obj":
|
||||
var s = initPrivateKey(pkbytes)
|
||||
var s = PrivateKey.fromHex(pkbytes)[]
|
||||
var mhash = keccak256.digest(message)
|
||||
var signature = s.signMessage(message)
|
||||
var p = recoverKeyFromSignature(signature, mhash)
|
||||
var signature = s.sign(message)[]
|
||||
var p = recover(signature, mhash)
|
||||
check:
|
||||
s.getPublicKey() == p
|
||||
s.toPublicKey() == p
|
||||
|
||||
test "test_to_address_from_public_key":
|
||||
var s = initPrivateKey(pkbytes)
|
||||
var chk = s.getPublicKey().toAddress()
|
||||
var s = PrivateKey.fromHex(pkbytes)[]
|
||||
var chk = s.toPublicKey()[].toAddress()
|
||||
var expect = "0x" & address
|
||||
check chk == expect
|
||||
|
||||
test "test_to_canonical_address_from_public_key":
|
||||
var s = initPrivateKey(pkbytes)
|
||||
var chk = s.getPublicKey().toCanonicalAddress()
|
||||
var s = PrivateKey.fromHex(pkbytes)[]
|
||||
var chk = s.toPublicKey()[].toCanonicalAddress()
|
||||
var expect = fromHex(stripSpaces(address))
|
||||
check compare(chk, expect) == true
|
||||
|
||||
test "test_to_checksum_address_from_public_key":
|
||||
var s = initPrivateKey(pkbytes)
|
||||
var chk = s.getPublicKey().toChecksumAddress()
|
||||
var s = PrivateKey.fromHex(pkbytes)[]
|
||||
var chk = s.toPublicKey()[].toChecksumAddress()
|
||||
var expect = "0x" & address
|
||||
check:
|
||||
chk.toLowerAscii() == expect
|
||||
|
@ -124,7 +128,7 @@ suite "ECC/ECDSA/ECDHE tests suite":
|
|||
|
||||
test "EIP-55 100 addresses":
|
||||
for i in 1..100:
|
||||
var kp = newKeyPair()
|
||||
var kp = KeyPair.random()[]
|
||||
var chaddress = kp.pubkey.toChecksumAddress()
|
||||
var noaddress = kp.pubkey.toAddress()
|
||||
if noaddress != chaddress:
|
||||
|
@ -149,13 +153,12 @@ suite "ECC/ECDSA/ECDHE tests suite":
|
|||
"ee1418607c2fcfb57fda40380e885a707f49000a5dda056d828b7d9bd1f29a08",
|
||||
"167ccc13ac5e8a26b131c3446030c60fbfac6aa8e31149d0869f93626a4cdf62"
|
||||
]
|
||||
var secret: SharedSecret
|
||||
for i in 0..1:
|
||||
var s = privateKeys[i].initPrivateKey()
|
||||
var p = publicKeys[i].initPublicKey()
|
||||
var s = PrivateKey.fromHex(privateKeys[i])[]
|
||||
var p = PublicKey.fromHex(stripSpaces(publicKeys[i]))[]
|
||||
let expect = fromHex(stripSpaces(sharedSecrets[i]))
|
||||
let secret = ecdhRaw(s, p)[]
|
||||
check:
|
||||
ecdhAgree(s, p, secret) == EthKeysStatus.Success
|
||||
expect == secret.data
|
||||
|
||||
test "ECDHE/cpp-ethereum crypto.cpp#L394":
|
||||
|
@ -163,12 +166,11 @@ suite "ECC/ECDSA/ECDHE tests suite":
|
|||
# Copied from https://github.com/ethereum/cpp-ethereum/blob/develop/test/unittests/libdevcrypto/crypto.cpp#L394
|
||||
var expectm = """
|
||||
8ac7e464348b85d9fdfc0a81f2fdc0bbbb8ee5fb3840de6ed60ad9372e718977"""
|
||||
var secret: SharedSecret
|
||||
var s = initPrivateKey(keccak256.digest("ecdhAgree").data)
|
||||
var p = s.getPublicKey()
|
||||
var s = PrivateKey.fromRaw(keccak256.digest("ecdhAgree").data)[]
|
||||
var p = s.toPublicKey()[]
|
||||
let expect = fromHex(stripSpaces(expectm))
|
||||
let secret = ecdhRaw(s, p)[]
|
||||
check:
|
||||
ecdhAgree(s, p, secret) == EthKeysStatus.Success
|
||||
expect == secret.data
|
||||
|
||||
test "ECDHE/cpp-ethereum rlpx.cpp#L425":
|
||||
|
@ -181,12 +183,11 @@ suite "ECC/ECDSA/ECDHE tests suite":
|
|||
7f0821367332598b6aa4e180a41e92f4ebbae3518da847f0b1c0bbfe20bcf4e1"""
|
||||
var e0 = """
|
||||
ee1418607c2fcfb57fda40380e885a707f49000a5dda056d828b7d9bd1f29a08"""
|
||||
var secret: SharedSecret
|
||||
var s = initPrivateKey(s0)
|
||||
var p = initPublicKey(p0)
|
||||
var s = PrivateKey.fromHex(stripSpaces(s0))[]
|
||||
var p = PublicKey.fromHex(stripSpaces(p0))[]
|
||||
let expect = fromHex(stripSpaces(e0))
|
||||
let secret = ecdhRaw(s, p)[]
|
||||
check:
|
||||
ecdhAgree(s, p, secret) == Success
|
||||
compare(expect, secret.data) == true
|
||||
|
||||
test "ECDSA/cpp-ethereum crypto.cpp#L132":
|
||||
|
@ -200,72 +201,62 @@ suite "ECC/ECDSA/ECDHE tests suite":
|
|||
84453b0b24f49086feba0bd978bb4446bae8dff1e79fcc1e9cf482ec2d07c3"""
|
||||
var check1 = fromHex(stripSpaces(signature))
|
||||
var check2 = fromHex(stripSpaces(pubkey))
|
||||
var sig: Signature
|
||||
var key: PublicKey
|
||||
var s = initPrivateKey(keccak256.digest("sec").data)
|
||||
var m = keccak256.digest("msg").data
|
||||
check signRawMessage(m, s, sig) == Success
|
||||
var sersig = sig.getRaw()
|
||||
check recoverSignatureKey(sersig, m, key) == Success
|
||||
var serkey = key.getRaw()
|
||||
|
||||
var s = PrivateKey.fromRaw(keccak256.digest("sec").data)[]
|
||||
var m = keccak256.digest("msg")
|
||||
var sig = sign(s, m)[]
|
||||
var sersig = sig.toRaw()
|
||||
var key = recover(sig, m)[]
|
||||
var serkey = key.toRaw()
|
||||
check:
|
||||
compare(sersig, check1) == true
|
||||
compare(serkey, check2) == true
|
||||
|
||||
test "ECDSA/100 signatures":
|
||||
# signature test
|
||||
var rkey: PublicKey
|
||||
var sig: Signature
|
||||
for i in 1..100:
|
||||
var m = newPrivateKey().data
|
||||
var s = newPrivateKey()
|
||||
var key = s.getPublicKey()
|
||||
check signRawMessage(m, s, sig) == Success
|
||||
var sersig = sig.getRaw()
|
||||
var m = PrivateKey.random()[].toRaw
|
||||
var s = PrivateKey.random()[]
|
||||
var key = s.toPublicKey()[]
|
||||
let sig = sign(s, m)[]
|
||||
let rkey = recover(sig, m)[]
|
||||
check:
|
||||
recoverSignatureKey(sersig, m, rkey) == Success
|
||||
key == rkey
|
||||
|
||||
test "KEYS/100 create/recovery keys":
|
||||
# key create/recovery test
|
||||
var rkey: PublicKey
|
||||
for i in 1..100:
|
||||
var s = newPrivateKey()
|
||||
var key = s.getPublicKey()
|
||||
var s = PrivateKey.random()[]
|
||||
var key = s.toPublicKey()[]
|
||||
let rkey = PublicKey.fromRaw(key.toRaw())[]
|
||||
check:
|
||||
recoverPublicKey(key.getRaw(), rkey) == Success
|
||||
key == rkey
|
||||
|
||||
test "ECDHE/100 shared secrets":
|
||||
# ECDHE shared secret test
|
||||
var secret1, secret2: SharedSecret
|
||||
for i in 1..100:
|
||||
var aliceSecret = newPrivateKey()
|
||||
var alicePublic = aliceSecret.getPublicKey()
|
||||
var bobSecret = newPrivateKey()
|
||||
var bobPublic = bobSecret.getPublicKey()
|
||||
var aliceSecret = PrivateKey.random()[]
|
||||
var alicePublic = aliceSecret.toPublicKey()[]
|
||||
var bobSecret = PrivateKey.random()[]
|
||||
var bobPublic = bobSecret.toPublicKey()[]
|
||||
var secret1 = ecdhRaw(aliceSecret, bobPublic)[]
|
||||
var secret2 = ecdhRaw(bobSecret, alicePublic)[]
|
||||
check:
|
||||
ecdhAgree(aliceSecret, bobPublic, secret1) == Success
|
||||
ecdhAgree(bobSecret, alicePublic, secret2) == Success
|
||||
secret1 == secret2
|
||||
|
||||
test "isZeroKey() checks":
|
||||
test "verfiy() checks":
|
||||
var seckey1: PrivateKey
|
||||
var pubkey1: PublicKey
|
||||
var seckey2 = newPrivateKey()
|
||||
var pubkey2 = seckey2.getPublicKey()
|
||||
var seckey2 = PrivateKey.random()[]
|
||||
|
||||
check:
|
||||
seckey1.isZeroKey() == true
|
||||
pubkey1.isZeroKey() == true
|
||||
seckey2.isZeroKey() == false
|
||||
pubkey2.isZeroKey() == false
|
||||
seckey1.verify() == false
|
||||
seckey2.verify() == true
|
||||
|
||||
test "Compressed public keys":
|
||||
let pubkeyCompressed = "03CA634CAE0D49ACB401D8A4C6B6FE8C55B70D115BF400769CC1400F3258CD3138"
|
||||
let s = initPublicKey(pubkeyCompressed)
|
||||
let pubkeyCompressed = "03CA634CAE0D49ACB401D8A4C6B6FE8C55B70D115BF400769CC1400F3258CD3138".toLowerAscii
|
||||
let s = PublicKey.fromHex(pubkeyCompressed)[]
|
||||
check:
|
||||
s.getRaw.toHex == """CA634CAE0D49ACB401D8A4C6B6FE8C55B70D115BF400769CC1400F3258
|
||||
CD31387574077F301B421BC84DF7266C44E9E6D569FC56BE00812904767BF5CCD1FC7F""".stripSpaces
|
||||
s.toRaw.toHex == """CA634CAE0D49ACB401D8A4C6B6FE8C55B70D115BF400769CC1400F3258
|
||||
CD31387574077F301B421BC84DF7266C44E9E6D569FC56BE00812904767BF5CCD1FC7F""".stripSpaces.toLowerAscii
|
||||
|
||||
s.getRawCompressed.toHex == pubkeyCompressed
|
||||
s.toRawCompressed.toHex == pubkeyCompressed
|
||||
|
|
|
@ -16,12 +16,12 @@ suite "Testing private -> public key conversion":
|
|||
test "Known private to known public keys (test data from Ethereum eth-keys)":
|
||||
for person in [alice, bob, eve]:
|
||||
let
|
||||
privKey = initPrivateKey(person.privkey)
|
||||
pubKey = privKey.getPublicKey
|
||||
privKey = PrivateKey.fromHex(person.privkey)[]
|
||||
pubKey = privKey.toPublicKey()[]
|
||||
|
||||
check:
|
||||
# Compare as strings
|
||||
$pubKey == person.pubkey
|
||||
|
||||
# Compare as keys
|
||||
pubKey == initPublicKey(person.pubkey)
|
||||
pubKey == PublicKey.fromHex(person.pubkey)[]
|
||||
|
|
|
@ -22,7 +22,7 @@ template asyncTest(name, body: untyped) =
|
|||
|
||||
asyncTest "network with 3 peers using the Whisper protocol":
|
||||
const useCompression = defined(useSnappy)
|
||||
let localKeys = newKeyPair()
|
||||
let localKeys = KeyPair.random()[]
|
||||
let localAddress = localAddress(30303)
|
||||
var localNode = newEthereumNode(localKeys, localAddress, 1, nil,
|
||||
addAllCapabilities = false,
|
||||
|
|
|
@ -17,13 +17,13 @@ proc startDiscoveryNode*(privKey: PrivateKey, address: Address,
|
|||
|
||||
proc setupBootNode*(): Future[ENode] {.async.} =
|
||||
let
|
||||
bootNodeKey = newPrivateKey()
|
||||
bootNodeKey = KeyPair.random()[]
|
||||
bootNodeAddr = localAddress(30301)
|
||||
bootNode = await startDiscoveryNode(bootNodeKey, bootNodeAddr, @[])
|
||||
result = initENode(bootNodeKey.getPublicKey, bootNodeAddr)
|
||||
bootNode = await startDiscoveryNode(bootNodeKey.seckey, bootNodeAddr, @[])
|
||||
result = initENode(bootNodeKey.pubkey, bootNodeAddr)
|
||||
|
||||
proc setupTestNode*(capabilities: varargs[ProtocolInfo, `protocolInfo`]): EthereumNode =
|
||||
let keys1 = newKeyPair()
|
||||
let keys1 = KeyPair.random()[]
|
||||
result = newEthereumNode(keys1, localAddress(nextPort), 1, nil,
|
||||
addAllCapabilities = false)
|
||||
nextPort.inc
|
||||
|
@ -45,7 +45,7 @@ template procSuite*(name, body: untyped) =
|
|||
proc packData*(payload: openArray[byte], pk: PrivateKey): seq[byte] =
|
||||
let
|
||||
payloadSeq = @payload
|
||||
signature = @(pk.signMessage(payload).getRaw())
|
||||
signature = @(pk.sign(payload).tryGet().toRaw())
|
||||
msgHash = keccak256.digest(signature & payloadSeq)
|
||||
result = @(msgHash.data) & signature & payloadSeq
|
||||
|
||||
|
|
|
@ -79,15 +79,17 @@ if config.main:
|
|||
else:
|
||||
netId = 15
|
||||
|
||||
let keypair = newKeyPair()
|
||||
let keypair = KeyPair.random()[]
|
||||
var node = newEthereumNode(keypair, address, netId, nil, addAllCapabilities = false)
|
||||
node.addCapability Whisper
|
||||
|
||||
# lets prepare some prearranged keypairs
|
||||
let encPrivateKey = initPrivateKey("5dc5381cae54ba3174dc0d46040fe11614d0cc94d41185922585198b4fcef9d3")
|
||||
let encPublicKey = encPrivateKey.getPublicKey()
|
||||
let signPrivateKey = initPrivateKey("365bda0757d22212b04fada4b9222f8c3da59b49398fa04cf612481cd893b0a3")
|
||||
let signPublicKey = signPrivateKey.getPublicKey()
|
||||
let encPrivateKey = PrivateKey.fromHex(
|
||||
"5dc5381cae54ba3174dc0d46040fe11614d0cc94d41185922585198b4fcef9d3")[]
|
||||
let encPublicKey = encPrivateKey.toPublicKey()[]
|
||||
let signPrivateKey = PrivateKey.fromHex(
|
||||
"365bda0757d22212b04fada4b9222f8c3da59b49398fa04cf612481cd893b0a3")[]
|
||||
let signPublicKey = signPrivateKey.toPublicKey()[]
|
||||
var symKey: SymKey
|
||||
# To test with geth: all 0's key is invalid in geth console
|
||||
symKey[31] = 1
|
||||
|
|
|
@ -217,19 +217,19 @@ suite "Ethereum P2P handshake test suite":
|
|||
proc newTestHandshake(flags: set[HandshakeFlag]): Handshake =
|
||||
result = newHandshake(flags)
|
||||
if Initiator in flags:
|
||||
result.host.seckey = initPrivateKey(testValue("initiator_private_key"))
|
||||
result.host.pubkey = result.host.seckey.getPublicKey()
|
||||
result.host.seckey = PrivateKey.fromHex(testValue("initiator_private_key"))[]
|
||||
result.host.pubkey = result.host.seckey.toPublicKey()[]
|
||||
let epki = testValue("initiator_ephemeral_private_key")
|
||||
result.ephemeral.seckey = initPrivateKey(epki)
|
||||
result.ephemeral.pubkey = result.ephemeral.seckey.getPublicKey()
|
||||
result.ephemeral.seckey = PrivateKey.fromHex(epki)[]
|
||||
result.ephemeral.pubkey = result.ephemeral.seckey.toPublicKey()[]
|
||||
let nonce = fromHex(stripSpaces(testValue("initiator_nonce")))
|
||||
result.initiatorNonce[0..^1] = nonce[0..^1]
|
||||
elif Responder in flags:
|
||||
result.host.seckey = initPrivateKey(testValue("receiver_private_key"))
|
||||
result.host.pubkey = result.host.seckey.getPublicKey()
|
||||
result.host.seckey = PrivateKey.fromHex(testValue("receiver_private_key"))[]
|
||||
result.host.pubkey = result.host.seckey.toPublicKey()[]
|
||||
let epkr = testValue("receiver_ephemeral_private_key")
|
||||
result.ephemeral.seckey = initPrivateKey(epkr)
|
||||
result.ephemeral.pubkey = result.ephemeral.seckey.getPublicKey()
|
||||
result.ephemeral.seckey = PrivateKey.fromHex(epkr)[]
|
||||
result.ephemeral.pubkey = result.ephemeral.seckey.toPublicKey()[]
|
||||
let nonce = fromHex(stripSpaces(testValue("receiver_nonce")))
|
||||
result.responderNonce[0..^1] = nonce[0..^1]
|
||||
|
||||
|
@ -252,15 +252,15 @@ suite "Ethereum P2P handshake test suite":
|
|||
var responder = newTestHandshake({Responder})
|
||||
var m0 = newSeq[byte](initiator.authSize())
|
||||
var k0 = 0
|
||||
let remoteEPubkey0 = initiator.ephemeral.pubkey.data
|
||||
let remoteHPubkey0 = initiator.host.pubkey.data
|
||||
let remoteEPubkey0 = initiator.ephemeral.pubkey
|
||||
let remoteHPubkey0 = initiator.host.pubkey
|
||||
check:
|
||||
initiator.authMessage(responder.host.pubkey,
|
||||
m0, k0) == AuthStatus.Success
|
||||
responder.decodeAuthMessage(m0) == AuthStatus.Success
|
||||
responder.initiatorNonce[0..^1] == initiator.initiatorNonce[0..^1]
|
||||
responder.remoteEPubkey.data[0..^1] == remoteEPubkey0[0..^1]
|
||||
responder.remoteHPubkey.data[0..^1] == remoteHPubkey0[0..^1]
|
||||
responder.remoteEPubkey == remoteEPubkey0
|
||||
responder.remoteHPubkey == remoteHPubkey0
|
||||
|
||||
test "ACK message expectation":
|
||||
var initiator = newTestHandshake({Initiator})
|
||||
|
@ -291,11 +291,11 @@ suite "Ethereum P2P handshake test suite":
|
|||
responder.decodeAuthMessage(m0) == AuthStatus.Success
|
||||
responder.ackMessage(m1, k1) == AuthStatus.Success
|
||||
initiator.decodeAckMessage(m1) == AuthStatus.Success
|
||||
let remoteEPubkey0 = responder.ephemeral.pubkey.data
|
||||
let remoteHPubkey0 = responder.host.pubkey.data
|
||||
let remoteEPubkey0 = responder.ephemeral.pubkey
|
||||
let remoteHPubkey0 = responder.host.pubkey
|
||||
check:
|
||||
initiator.remoteEPubkey.data[0..^1] == remoteEPubkey0[0..^1]
|
||||
initiator.remoteHPubkey.data[0..^1] == remoteHPubkey0[0..^1]
|
||||
initiator.remoteEPubkey == remoteEPubkey0
|
||||
initiator.remoteHPubkey == remoteHPubkey0
|
||||
initiator.responderNonce == responder.responderNonce
|
||||
|
||||
test "Check derived secrets":
|
||||
|
@ -332,19 +332,19 @@ suite "Ethereum P2P handshake test suite":
|
|||
proc newTestHandshake(flags: set[HandshakeFlag]): Handshake =
|
||||
result = newHandshake(flags)
|
||||
if Initiator in flags:
|
||||
result.host.seckey = initPrivateKey(testE8Value("initiator_private_key"))
|
||||
result.host.pubkey = result.host.seckey.getPublicKey()
|
||||
result.host.seckey = PrivateKey.fromHex(testE8Value("initiator_private_key"))[]
|
||||
result.host.pubkey = result.host.seckey.toPublicKey()[]
|
||||
let esec = testE8Value("initiator_ephemeral_private_key")
|
||||
result.ephemeral.seckey = initPrivateKey(esec)
|
||||
result.ephemeral.pubkey = result.ephemeral.seckey.getPublicKey()
|
||||
result.ephemeral.seckey = PrivateKey.fromHex(esec)[]
|
||||
result.ephemeral.pubkey = result.ephemeral.seckey.toPublicKey()[]
|
||||
let nonce = fromHex(stripSpaces(testE8Value("initiator_nonce")))
|
||||
result.initiatorNonce[0..^1] = nonce[0..^1]
|
||||
elif Responder in flags:
|
||||
result.host.seckey = initPrivateKey(testE8Value("receiver_private_key"))
|
||||
result.host.pubkey = result.host.seckey.getPublicKey()
|
||||
result.host.seckey = PrivateKey.fromHex(testE8Value("receiver_private_key"))[]
|
||||
result.host.pubkey = result.host.seckey.toPublicKey()[]
|
||||
let esec = testE8Value("receiver_ephemeral_private_key")
|
||||
result.ephemeral.seckey = initPrivateKey(esec)
|
||||
result.ephemeral.pubkey = result.ephemeral.seckey.getPublicKey()
|
||||
result.ephemeral.seckey = PrivateKey.fromHex(esec)[]
|
||||
result.ephemeral.pubkey = result.ephemeral.seckey.toPublicKey()[]
|
||||
let nonce = fromHex(stripSpaces(testE8Value("receiver_nonce")))
|
||||
result.responderNonce[0..^1] = nonce[0..^1]
|
||||
|
||||
|
@ -355,16 +355,16 @@ suite "Ethereum P2P handshake test suite":
|
|||
check:
|
||||
responder.decodeAuthMessage(m0) == AuthStatus.Success
|
||||
responder.initiatorNonce[0..^1] == initiator.initiatorNonce[0..^1]
|
||||
let remoteEPubkey0 = initiator.ephemeral.pubkey.data
|
||||
let remoteHPubkey0 = initiator.host.pubkey.data
|
||||
let remoteEPubkey0 = initiator.ephemeral.pubkey
|
||||
let remoteHPubkey0 = initiator.host.pubkey
|
||||
check:
|
||||
responder.remoteEPubkey.data[0..^1] == remoteEPubkey0[0..^1]
|
||||
responder.remoteHPubkey.data[0..^1] == remoteHPubkey0[0..^1]
|
||||
responder.remoteEPubkey == remoteEPubkey0
|
||||
responder.remoteHPubkey == remoteHPubkey0
|
||||
var m1 = fromHex(stripSpaces(testE8Value("authack_ciphertext_v4")))
|
||||
check initiator.decodeAckMessage(m1) == AuthStatus.Success
|
||||
let remoteEPubkey1 = responder.ephemeral.pubkey.data
|
||||
let remoteEPubkey1 = responder.ephemeral.pubkey
|
||||
check:
|
||||
initiator.remoteEPubkey.data[0..^1] == remoteEPubkey1[0..^1]
|
||||
initiator.remoteEPubkey == remoteEPubkey1
|
||||
initiator.responderNonce[0..^1] == responder.responderNonce[0..^1]
|
||||
|
||||
test "AUTH/ACK EIP-8 test vectors":
|
||||
|
@ -374,15 +374,15 @@ suite "Ethereum P2P handshake test suite":
|
|||
check:
|
||||
responder.decodeAuthMessage(m0) == AuthStatus.Success
|
||||
responder.initiatorNonce[0..^1] == initiator.initiatorNonce[0..^1]
|
||||
let remoteEPubkey0 = initiator.ephemeral.pubkey.data
|
||||
check responder.remoteEPubkey.data[0..^1] == remoteEPubkey0[0..^1]
|
||||
let remoteHPubkey0 = initiator.host.pubkey.data
|
||||
check responder.remoteHPubkey.data[0..^1] == remoteHPubkey0[0..^1]
|
||||
let remoteEPubkey0 = initiator.ephemeral.pubkey
|
||||
check responder.remoteEPubkey == remoteEPubkey0
|
||||
let remoteHPubkey0 = initiator.host.pubkey
|
||||
check responder.remoteHPubkey == remoteHPubkey0
|
||||
var m1 = fromHex(stripSpaces(testE8Value("authack_ciphertext_eip8")))
|
||||
check initiator.decodeAckMessage(m1) == AuthStatus.Success
|
||||
let remoteEPubkey1 = responder.ephemeral.pubkey.data
|
||||
let remoteEPubkey1 = responder.ephemeral.pubkey
|
||||
check:
|
||||
initiator.remoteEPubkey.data[0..^1] == remoteEPubkey1[0..^1]
|
||||
initiator.remoteEPubkey == remoteEPubkey1
|
||||
initiator.responderNonce[0..^1] == responder.responderNonce[0..^1]
|
||||
var taes = fromHex(stripSpaces(testE8Value("auth2ack2_aes_secret")))
|
||||
var tmac = fromHex(stripSpaces(testE8Value("auth2ack2_mac_secret")))
|
||||
|
@ -410,18 +410,18 @@ suite "Ethereum P2P handshake test suite":
|
|||
check:
|
||||
responder.decodeAuthMessage(m0) == AuthStatus.Success
|
||||
responder.initiatorNonce[0..^1] == initiator.initiatorNonce[0..^1]
|
||||
let remoteEPubkey0 = initiator.ephemeral.pubkey.data
|
||||
let remoteHPubkey0 = initiator.host.pubkey.data
|
||||
let remoteEPubkey0 = initiator.ephemeral.pubkey
|
||||
let remoteHPubkey0 = initiator.host.pubkey
|
||||
check:
|
||||
responder.remoteEPubkey.data[0..^1] == remoteEPubkey0[0..^1]
|
||||
responder.remoteHPubkey.data[0..^1] == remoteHPubkey0[0..^1]
|
||||
responder.remoteEPubkey == remoteEPubkey0
|
||||
responder.remoteHPubkey == remoteHPubkey0
|
||||
var m1 = fromHex(stripSpaces(testE8Value("authack_ciphertext_eip8_3f")))
|
||||
check initiator.decodeAckMessage(m1) == AuthStatus.Success
|
||||
let remoteEPubkey1 = responder.ephemeral.pubkey.data
|
||||
let remoteEPubkey1 = responder.ephemeral.pubkey
|
||||
check:
|
||||
int(initiator.version) == 57
|
||||
int(responder.version) == 56
|
||||
initiator.remoteEPubkey.data[0..^1] == remoteEPubkey1[0..^1]
|
||||
initiator.remoteEPubkey == remoteEPubkey1
|
||||
initiator.responderNonce[0..^1] == responder.responderNonce[0..^1]
|
||||
|
||||
test "100 AUTH/ACK EIP-8 handshakes":
|
||||
|
|
|
@ -90,19 +90,19 @@ suite "Ethereum RLPx encryption/decryption test suite":
|
|||
proc newTestHandshake(flags: set[HandshakeFlag]): Handshake =
|
||||
result = newHandshake(flags)
|
||||
if Initiator in flags:
|
||||
result.host.seckey = initPrivateKey(testValue("initiator_private_key"))
|
||||
result.host.pubkey = result.host.seckey.getPublicKey()
|
||||
result.host.seckey = PrivateKey.fromHex(testValue("initiator_private_key"))[]
|
||||
result.host.pubkey = result.host.seckey.toPublicKey()[]
|
||||
let epki = testValue("initiator_ephemeral_private_key")
|
||||
result.ephemeral.seckey = initPrivateKey(epki)
|
||||
result.ephemeral.pubkey = result.ephemeral.seckey.getPublicKey()
|
||||
result.ephemeral.seckey = PrivateKey.fromHex(epki)[]
|
||||
result.ephemeral.pubkey = result.ephemeral.seckey.toPublicKey()[]
|
||||
let nonce = fromHex(stripSpaces(testValue("initiator_nonce")))
|
||||
result.initiatorNonce[0..^1] = nonce[0..^1]
|
||||
elif Responder in flags:
|
||||
result.host.seckey = initPrivateKey(testValue("receiver_private_key"))
|
||||
result.host.pubkey = result.host.seckey.getPublicKey()
|
||||
result.host.seckey = PrivateKey.fromHex(testValue("receiver_private_key"))[]
|
||||
result.host.pubkey = result.host.seckey.toPublicKey()[]
|
||||
let epkr = testValue("receiver_ephemeral_private_key")
|
||||
result.ephemeral.seckey = initPrivateKey(epkr)
|
||||
result.ephemeral.pubkey = result.ephemeral.seckey.getPublicKey()
|
||||
result.ephemeral.seckey = PrivateKey.fromHex(epkr)[]
|
||||
result.ephemeral.pubkey = result.ephemeral.seckey.toPublicKey()[]
|
||||
let nonce = fromHex(stripSpaces(testValue("receiver_nonce")))
|
||||
result.responderNonce[0..^1] = nonce[0..^1]
|
||||
|
||||
|
|
|
@ -19,16 +19,20 @@ proc nodeIdInNodes(id: NodeId, nodes: openarray[Node]): bool =
|
|||
proc test() {.async.} =
|
||||
suite "Discovery Tests":
|
||||
let
|
||||
bootNodeKey = initPrivateKey("a2b50376a79b1a8c8a3296485572bdfbf54708bb46d3c25d73d2723aaaf6a617")
|
||||
bootNodeKey = PrivateKey.fromHex(
|
||||
"a2b50376a79b1a8c8a3296485572bdfbf54708bb46d3c25d73d2723aaaf6a617")[]
|
||||
bootNodeAddr = localAddress(20301)
|
||||
bootENode = initENode(bootNodeKey.getPublicKey, bootNodeAddr)
|
||||
bootENode = initENode(bootNodeKey.toPublicKey()[], bootNodeAddr)
|
||||
bootNode = await startDiscoveryNode(bootNodeKey, bootNodeAddr, @[])
|
||||
|
||||
test "Discover nodes":
|
||||
let nodeKeys = [
|
||||
initPrivateKey("a2b50376a79b1a8c8a3296485572bdfbf54708bb46d3c25d73d2723aaaf6a618"),
|
||||
initPrivateKey("a2b50376a79b1a8c8a3296485572bdfbf54708bb46d3c25d73d2723aaaf6a619"),
|
||||
initPrivateKey("a2b50376a79b1a8c8a3296485572bdfbf54708bb46d3c25d73d2723aaaf6a620")
|
||||
PrivateKey.fromHex(
|
||||
"a2b50376a79b1a8c8a3296485572bdfbf54708bb46d3c25d73d2723aaaf6a618")[],
|
||||
PrivateKey.fromHex(
|
||||
"a2b50376a79b1a8c8a3296485572bdfbf54708bb46d3c25d73d2723aaaf6a619")[],
|
||||
PrivateKey.fromHex(
|
||||
"a2b50376a79b1a8c8a3296485572bdfbf54708bb46d3c25d73d2723aaaf6a620")[]
|
||||
]
|
||||
var nodeAddrs = newSeqOfCap[Address](nodeKeys.len)
|
||||
for i in 0 ..< nodeKeys.len: nodeAddrs.add(localAddress(20302 + i))
|
||||
|
@ -62,7 +66,8 @@ proc test() {.async.} =
|
|||
]
|
||||
let
|
||||
address = localAddress(20302)
|
||||
nodeKey = initPrivateKey("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
||||
nodeKey = PrivateKey.fromHex(
|
||||
"b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")[]
|
||||
|
||||
for data in validProtocolData:
|
||||
# none of these may raise
|
||||
|
@ -80,7 +85,8 @@ proc test() {.async.} =
|
|||
]
|
||||
let
|
||||
address = localAddress(20302)
|
||||
nodeKey = initPrivateKey("a2b50376a79b1a8c8a3296485572bdfbf54708bb46d3c25d73d2723aaaf6a618")
|
||||
nodeKey = PrivateKey.fromHex(
|
||||
"a2b50376a79b1a8c8a3296485572bdfbf54708bb46d3c25d73d2723aaaf6a618")[]
|
||||
|
||||
for data in invalidProtocolData:
|
||||
expect DiscProtocolError:
|
||||
|
|
|
@ -26,13 +26,13 @@ proc randomPacket(tag: PacketTag): seq[byte] =
|
|||
authTag: AuthTag
|
||||
msg: array[44, byte]
|
||||
|
||||
randomBytes(authTag)
|
||||
randomBytes(msg)
|
||||
randomBytes2(authTag)
|
||||
randomBytes2(msg)
|
||||
result.add(tag)
|
||||
result.add(rlp.encode(authTag))
|
||||
result.add(msg)
|
||||
|
||||
proc generateNode(privKey = newPrivateKey(), port: int): Node =
|
||||
proc generateNode(privKey = PrivateKey.random()[], port: int): Node =
|
||||
let port = Port(port)
|
||||
let enr = enr.Record.init(1, privKey, some(parseIpAddress("127.0.0.1")),
|
||||
port, port)
|
||||
|
@ -41,13 +41,17 @@ proc generateNode(privKey = newPrivateKey(), port: int): Node =
|
|||
suite "Discovery v5 Tests":
|
||||
asyncTest "Random nodes":
|
||||
let
|
||||
bootNodeKey = initPrivateKey("a2b50376a79b1a8c8a3296485572bdfbf54708bb46d3c25d73d2723aaaf6a617")
|
||||
bootNodeKey = PrivateKey.fromHex(
|
||||
"a2b50376a79b1a8c8a3296485572bdfbf54708bb46d3c25d73d2723aaaf6a617")[]
|
||||
bootNode = initDiscoveryNode(bootNodeKey, localAddress(20301))
|
||||
|
||||
let nodeKeys = [
|
||||
initPrivateKey("a2b50376a79b1a8c8a3296485572bdfbf54708bb46d3c25d73d2723aaaf6a618"),
|
||||
initPrivateKey("a2b50376a79b1a8c8a3296485572bdfbf54708bb46d3c25d73d2723aaaf6a619"),
|
||||
initPrivateKey("a2b50376a79b1a8c8a3296485572bdfbf54708bb46d3c25d73d2723aaaf6a620")
|
||||
PrivateKey.fromHex(
|
||||
"a2b50376a79b1a8c8a3296485572bdfbf54708bb46d3c25d73d2723aaaf6a618")[],
|
||||
PrivateKey.fromHex(
|
||||
"a2b50376a79b1a8c8a3296485572bdfbf54708bb46d3c25d73d2723aaaf6a619")[],
|
||||
PrivateKey.fromHex(
|
||||
"a2b50376a79b1a8c8a3296485572bdfbf54708bb46d3c25d73d2723aaaf6a620")[]
|
||||
]
|
||||
var nodeAddrs = newSeqOfCap[Address](nodeKeys.len)
|
||||
for i in 0 ..< nodeKeys.len: nodeAddrs.add(localAddress(20302 + i))
|
||||
|
@ -74,13 +78,13 @@ suite "Discovery v5 Tests":
|
|||
const
|
||||
nodeCount = 17
|
||||
|
||||
let bootNode = initDiscoveryNode(newPrivateKey(), localAddress(20301))
|
||||
let bootNode = initDiscoveryNode(PrivateKey.random()[], localAddress(20301))
|
||||
bootNode.start()
|
||||
|
||||
var nodes = newSeqOfCap[discv5_protocol.Protocol](nodeCount)
|
||||
nodes.add(bootNode)
|
||||
for i in 1 ..< nodeCount:
|
||||
nodes.add(initDiscoveryNode(newPrivateKey(), localAddress(20301 + i),
|
||||
nodes.add(initDiscoveryNode(PrivateKey.random()[], localAddress(20301 + i),
|
||||
@[bootNode.localNode.record]))
|
||||
nodes[i].start()
|
||||
|
||||
|
@ -96,7 +100,7 @@ suite "Discovery v5 Tests":
|
|||
|
||||
asyncTest "FindNode with test table":
|
||||
|
||||
let mainNode = initDiscoveryNode(newPrivateKey(), localAddress(20301))
|
||||
let mainNode = initDiscoveryNode(PrivateKey.random()[], localAddress(20301))
|
||||
|
||||
# Generate 1000 random nodes and add to our main node's routing table
|
||||
for i in 0..<1000:
|
||||
|
@ -110,7 +114,7 @@ suite "Discovery v5 Tests":
|
|||
debug "Closest neighbour", closestDistance, id=closest.id.toHex()
|
||||
|
||||
let
|
||||
testNode = initDiscoveryNode(newPrivateKey(), localAddress(20302),
|
||||
testNode = initDiscoveryNode(PrivateKey.random()[], localAddress(20302),
|
||||
@[mainNode.localNode.record])
|
||||
discovered = await discv5_protocol.findNode(testNode, mainNode.localNode,
|
||||
closestDistance)
|
||||
|
@ -123,7 +127,7 @@ suite "Discovery v5 Tests":
|
|||
asyncTest "GetNode":
|
||||
# TODO: This could be tested in just a routing table only context
|
||||
let
|
||||
node = initDiscoveryNode(newPrivateKey(), localAddress(20302))
|
||||
node = initDiscoveryNode(PrivateKey.random()[], localAddress(20302))
|
||||
targetNode = generateNode(port = 20303)
|
||||
|
||||
node.addNode(targetNode)
|
||||
|
@ -137,10 +141,10 @@ suite "Discovery v5 Tests":
|
|||
|
||||
asyncTest "Node deletion":
|
||||
let
|
||||
bootnode = initDiscoveryNode(newPrivateKey(), localAddress(20301))
|
||||
node1 = initDiscoveryNode(newPrivateKey(), localAddress(20302),
|
||||
bootnode = initDiscoveryNode(PrivateKey.random()[], localAddress(20301))
|
||||
node1 = initDiscoveryNode(PrivateKey.random()[], localAddress(20302),
|
||||
@[bootnode.localNode.record])
|
||||
node2 = initDiscoveryNode(newPrivateKey(), localAddress(20303),
|
||||
node2 = initDiscoveryNode(PrivateKey.random()[], localAddress(20303),
|
||||
@[bootnode.localNode.record])
|
||||
pong1 = await discv5_protocol.ping(node1, bootnode.localNode)
|
||||
pong2 = await discv5_protocol.ping(node1, node2.localNode)
|
||||
|
@ -160,12 +164,12 @@ suite "Discovery v5 Tests":
|
|||
|
||||
|
||||
asyncTest "Handshake cleanup":
|
||||
let node = initDiscoveryNode(newPrivateKey(), localAddress(20302))
|
||||
let node = initDiscoveryNode(PrivateKey.random()[], localAddress(20302))
|
||||
var tag: PacketTag
|
||||
let a = localAddress(20303)
|
||||
|
||||
for i in 0 ..< 5:
|
||||
randomBytes(tag)
|
||||
randomBytes2(tag)
|
||||
node.receive(a, randomPacket(tag))
|
||||
|
||||
# Checking different nodeIds but same address
|
||||
|
@ -179,7 +183,7 @@ suite "Discovery v5 Tests":
|
|||
await node.closeWait()
|
||||
|
||||
asyncTest "Handshake different address":
|
||||
let node = initDiscoveryNode(newPrivateKey(), localAddress(20302))
|
||||
let node = initDiscoveryNode(PrivateKey.random()[], localAddress(20302))
|
||||
var tag: PacketTag
|
||||
|
||||
for i in 0 ..< 5:
|
||||
|
@ -191,7 +195,7 @@ suite "Discovery v5 Tests":
|
|||
await node.closeWait()
|
||||
|
||||
asyncTest "Handshake duplicates":
|
||||
let node = initDiscoveryNode(newPrivateKey(), localAddress(20302))
|
||||
let node = initDiscoveryNode(PrivateKey.random()[], localAddress(20302))
|
||||
var tag: PacketTag
|
||||
let a = localAddress(20303)
|
||||
|
||||
|
@ -235,8 +239,8 @@ suite "Discovery v5 Tests":
|
|||
("8c5b422155d33ea8e9d46f71d1ad3e7b24cb40051413ffa1a81cff613d243ba9", 256'u32)
|
||||
]
|
||||
|
||||
let targetId = toNodeId(initPublicKey(targetKey))
|
||||
let targetId = toNodeId(PublicKey.fromHex(targetKey)[])
|
||||
|
||||
for (key, d) in testValues:
|
||||
let id = toNodeId(initPrivateKey(key).getPublicKey())
|
||||
let id = toNodeId(PrivateKey.fromHex(key)[].toPublicKey()[])
|
||||
check logDist(targetId, id) == d
|
||||
|
|
|
@ -132,13 +132,12 @@ suite "Discovery v5 Cryptographic Primitives":
|
|||
sharedSecret = "0x033b11a2a1f214567e1537ce5e509ffd9b21373247f2a3ff6841f4976f53165e7e"
|
||||
|
||||
let
|
||||
pub = initPublicKey(publicKey)
|
||||
priv = initPrivateKey(secretKey)
|
||||
var eph: SharedSecretFull
|
||||
pub = PublicKey.fromHex(publicKey)[]
|
||||
priv = PrivateKey.fromHex(secretKey)[]
|
||||
|
||||
let eph = ecdhRawFull(priv, pub)
|
||||
check:
|
||||
ecdhAgree(priv, pub, eph) == EthKeysStatus.Success
|
||||
eph.data == hexToSeqByte(sharedSecret)
|
||||
eph[].data == hexToSeqByte(sharedSecret)
|
||||
|
||||
test "Key Derivation":
|
||||
# const
|
||||
|
@ -167,10 +166,10 @@ suite "Discovery v5 Cryptographic Primitives":
|
|||
idNonceSig = "0xc5036e702a79902ad8aa147dabfe3958b523fd6fa36cc78e2889b912d682d8d35fdea142e141f690736d86f50b39746ba2d2fc510b46f82ee08f08fd55d133a4"
|
||||
|
||||
let
|
||||
c = Codec(privKey: initPrivateKey(localSecretKey))
|
||||
c = Codec(privKey: PrivateKey.fromHex(localSecretKey)[])
|
||||
signature = signIDNonce(c, hexToByteArray[idNonceSize](idNonce),
|
||||
hexToByteArray[64](ephemeralKey))
|
||||
check signature.getRaw() == hexToByteArray[64](idNonceSig)
|
||||
check signature.toRaw() == hexToByteArray[64](idNonceSig)
|
||||
|
||||
test "Encryption/Decryption":
|
||||
const
|
||||
|
|
|
@ -69,8 +69,8 @@ suite "ECIES test suite":
|
|||
var encr = newSeq[byte](eciesEncryptedLength(len(m)))
|
||||
var decr = newSeq[byte](len(m))
|
||||
var shmac = [0x13'u8, 0x13'u8]
|
||||
var s = newPrivateKey()
|
||||
var p = s.getPublicKey()
|
||||
var s = PrivateKey.random()[]
|
||||
var p = s.toPublicKey()[]
|
||||
check:
|
||||
# Without additional mac data
|
||||
eciesEncrypt(plain, encr, p) == EciesStatus.Success
|
||||
|
@ -123,7 +123,7 @@ suite "ECIES test suite":
|
|||
]
|
||||
var data: array[1024, byte]
|
||||
for i in 0..1:
|
||||
var s = initPrivateKey(secretKeys[i])
|
||||
var s = PrivateKey.fromHex(secretKeys[i])[]
|
||||
var cipher = fromHex(stripSpaces(cipherText[i]))
|
||||
var expect = fromHex(stripSpaces(expectText[i]))
|
||||
check:
|
||||
|
@ -164,7 +164,7 @@ suite "ECIES test suite":
|
|||
]
|
||||
var data: array[1024, byte]
|
||||
for i in 0..3:
|
||||
var s = initPrivateKey(secretKeys[i])
|
||||
var s = PrivateKey.fromHex(secretKeys[i])[]
|
||||
var cipher = fromHex(stripSpaces(cipherData[i]))
|
||||
check:
|
||||
eciesDecrypt(cipher, data, s) == EciesStatus.Success
|
||||
|
|
|
@ -97,5 +97,5 @@ suite "ENode":
|
|||
check isCorrect(node) == false
|
||||
node.address.udpPort = Port(25)
|
||||
check isCorrect(node) == false
|
||||
node.pubkey.data[0] = 1'u8
|
||||
node.pubkey = PrivateKey.random()[].toPublicKey()[]
|
||||
check isCorrect(node) == true
|
||||
|
|
|
@ -5,7 +5,8 @@ import
|
|||
|
||||
suite "ENR":
|
||||
test "Serialization":
|
||||
var pk = initPrivateKey("5d2908f3f09ea1ff2e327c3f623159639b00af406e9009de5fd4b910fc34049d")
|
||||
var pk = PrivateKey.fromHex(
|
||||
"5d2908f3f09ea1ff2e327c3f623159639b00af406e9009de5fd4b910fc34049d")[]
|
||||
var r = initRecord(123, pk, {"udp": 1234'u, "ip": [byte 5, 6, 7, 8]})
|
||||
doAssert($r == """(id: "v4", ip: 0x05060708, secp256k1: 0x02E51EFA66628CE09F689BC2B82F165A75A9DDECBB6A804BE15AC3FDF41F3B34E7, udp: 1234)""")
|
||||
let uri = r.toURI()
|
||||
|
@ -32,14 +33,14 @@ suite "ENR":
|
|||
|
||||
test "Create from ENode address":
|
||||
let
|
||||
keys = newKeyPair()
|
||||
keys = KeyPair.random()[]
|
||||
ip = parseIpAddress("10.20.30.40")
|
||||
enr = Record.init(100, keys.seckey, some(ip), Port(9000), Port(9000))
|
||||
typedEnr = get enr.toTypedRecord()
|
||||
|
||||
check:
|
||||
typedEnr.secp256k1.isSome()
|
||||
typedEnr.secp256k1.get == keys.pubkey.getRawCompressed()
|
||||
typedEnr.secp256k1.get == keys.pubkey.toRawCompressed()
|
||||
|
||||
typedEnr.ip.isSome()
|
||||
typedEnr.ip.get() == [byte 10, 20, 30, 40]
|
||||
|
@ -52,13 +53,13 @@ suite "ENR":
|
|||
|
||||
test "ENR without address":
|
||||
let
|
||||
keys = newKeyPair()
|
||||
keys = KeyPair.random()[]
|
||||
enr = Record.init(100, keys.seckey, none(IpAddress), Port(9000), Port(9000))
|
||||
typedEnr = get enr.toTypedRecord()
|
||||
|
||||
check:
|
||||
typedEnr.secp256k1.isSome()
|
||||
typedEnr.secp256k1.get() == keys.pubkey.getRawCompressed()
|
||||
typedEnr.secp256k1.get() == keys.pubkey.toRawCompressed()
|
||||
|
||||
typedEnr.ip.isNone()
|
||||
typedEnr.tcp.isSome()
|
||||
|
|
|
@ -36,7 +36,7 @@ suite "Whisper payload":
|
|||
decoded.get().padding.get().len == 251 # 256 -1 -1 -3
|
||||
|
||||
test "should roundtrip with signature":
|
||||
let privKey = keys.newPrivateKey()
|
||||
let privKey = PrivateKey.random()[]
|
||||
|
||||
let payload = Payload(src: some(privKey), payload: @[byte 0, 1, 2])
|
||||
let encoded = whisper.encode(payload)
|
||||
|
@ -45,13 +45,13 @@ suite "Whisper payload":
|
|||
check:
|
||||
decoded.isSome()
|
||||
payload.payload == decoded.get().payload
|
||||
privKey.getPublicKey() == decoded.get().src.get()
|
||||
privKey.toPublicKey()[] == decoded.get().src.get()
|
||||
decoded.get().padding.get().len == 186 # 256 -1 -1 -3 -65
|
||||
|
||||
test "should roundtrip with asymmetric encryption":
|
||||
let privKey = keys.newPrivateKey()
|
||||
let privKey = PrivateKey.random()[]
|
||||
|
||||
let payload = Payload(dst: some(privKey.getPublicKey()),
|
||||
let payload = Payload(dst: some(privKey.toPublicKey()[]),
|
||||
payload: @[byte 0, 1, 2])
|
||||
let encoded = whisper.encode(payload)
|
||||
|
||||
|
@ -84,7 +84,7 @@ suite "Whisper payload padding":
|
|||
decoded.get().padding.get().len == 256 # as dataLen == 256
|
||||
|
||||
test "should do max padding with signature":
|
||||
let privKey = keys.newPrivateKey()
|
||||
let privKey = PrivateKey.random()[]
|
||||
|
||||
let payload = Payload(src: some(privKey), payload: repeat(byte 1, 189))
|
||||
let encoded = whisper.encode(payload)
|
||||
|
@ -93,7 +93,7 @@ suite "Whisper payload padding":
|
|||
check:
|
||||
decoded.isSome()
|
||||
payload.payload == decoded.get().payload
|
||||
privKey.getPublicKey() == decoded.get().src.get()
|
||||
privKey.toPublicKey()[] == decoded.get().src.get()
|
||||
decoded.get().padding.isSome()
|
||||
decoded.get().padding.get().len == 256 # as dataLen == 256
|
||||
|
||||
|
@ -109,7 +109,7 @@ suite "Whisper payload padding":
|
|||
decoded.get().padding.get().len == 1 # as dataLen == 255
|
||||
|
||||
test "should do min padding with signature":
|
||||
let privKey = keys.newPrivateKey()
|
||||
let privKey = PrivateKey.random()[]
|
||||
|
||||
let payload = Payload(src: some(privKey), payload: repeat(byte 1, 188))
|
||||
let encoded = whisper.encode(payload)
|
||||
|
@ -118,7 +118,7 @@ suite "Whisper payload padding":
|
|||
check:
|
||||
decoded.isSome()
|
||||
payload.payload == decoded.get().payload
|
||||
privKey.getPublicKey() == decoded.get().src.get()
|
||||
privKey.toPublicKey()[] == decoded.get().src.get()
|
||||
decoded.get().padding.isSome()
|
||||
decoded.get().padding.get().len == 1 # as dataLen == 255
|
||||
|
||||
|
@ -147,7 +147,7 @@ suite "Whisper payload padding":
|
|||
decoded.get().padding.isNone()
|
||||
|
||||
test "should roundtrip custom padding with signature":
|
||||
let privKey = keys.newPrivateKey()
|
||||
let privKey = PrivateKey.random()[]
|
||||
let payload = Payload(src: some(privKey), payload: repeat(byte 1, 10),
|
||||
padding: some(repeat(byte 2, 100)))
|
||||
let encoded = whisper.encode(payload)
|
||||
|
@ -156,13 +156,13 @@ suite "Whisper payload padding":
|
|||
check:
|
||||
decoded.isSome()
|
||||
payload.payload == decoded.get().payload
|
||||
privKey.getPublicKey() == decoded.get().src.get()
|
||||
privKey.toPublicKey()[] == decoded.get().src.get()
|
||||
decoded.get().padding.isSome()
|
||||
payload.padding.get() == decoded.get().padding.get()
|
||||
|
||||
test "should roundtrip custom 0 padding with signature":
|
||||
let padding: seq[byte] = @[]
|
||||
let privKey = keys.newPrivateKey()
|
||||
let privKey = PrivateKey.random()[]
|
||||
let payload = Payload(src: some(privKey), payload: repeat(byte 1, 10),
|
||||
padding: some(padding))
|
||||
let encoded = whisper.encode(payload)
|
||||
|
@ -171,7 +171,7 @@ suite "Whisper payload padding":
|
|||
check:
|
||||
decoded.isSome()
|
||||
payload.payload == decoded.get().payload
|
||||
privKey.getPublicKey() == decoded.get().src.get()
|
||||
privKey.toPublicKey()[] == decoded.get().src.get()
|
||||
decoded.get().padding.isNone()
|
||||
|
||||
# example from https://github.com/paritytech/parity-ethereum/blob/93e1040d07e385d1219d00af71c46c720b0a1acf/whisper/src/message.rs#L439
|
||||
|
@ -300,9 +300,9 @@ suite "Whisper filter":
|
|||
messages[0].dst.isNone()
|
||||
|
||||
test "should notify filter on message with asymmetric encryption":
|
||||
let privKey = keys.newPrivateKey()
|
||||
let privKey = PrivateKey.random()[]
|
||||
let topic = [byte 0, 0, 0, 0]
|
||||
let msg = prepFilterTestMsg(pubKey = some(privKey.getPublicKey()),
|
||||
let msg = prepFilterTestMsg(pubKey = some(privKey.toPublicKey()[]),
|
||||
topic = topic)
|
||||
|
||||
var filters = initTable[string, Filter]()
|
||||
|
@ -318,12 +318,12 @@ suite "Whisper filter":
|
|||
messages[0].dst.isSome()
|
||||
|
||||
test "should notify filter on message with signature":
|
||||
let privKey = keys.newPrivateKey()
|
||||
let privKey = PrivateKey.random()[]
|
||||
let topic = [byte 0, 0, 0, 0]
|
||||
let msg = prepFilterTestMsg(src = some(privKey), topic = topic)
|
||||
|
||||
var filters = initTable[string, Filter]()
|
||||
let filter = initFilter(src = some(privKey.getPublicKey()),
|
||||
let filter = initFilter(src = some(privKey.toPublicKey()[]),
|
||||
topics = @[topic])
|
||||
let filterId = filters.subscribeFilter(filter)
|
||||
|
||||
|
|
|
@ -30,8 +30,8 @@ procSuite "Whisper connections":
|
|||
node1.peerPool.connectedNodes.len() == 1
|
||||
|
||||
asyncTest "Filters with encryption and signing":
|
||||
let encryptKeyPair = newKeyPair()
|
||||
let signKeyPair = newKeyPair()
|
||||
let encryptKeyPair = KeyPair.random()[]
|
||||
let signKeyPair = KeyPair.random()[]
|
||||
var symKey: SymKey
|
||||
let topic = [byte 0x12, 0, 0, 0]
|
||||
var filters: seq[string] = @[]
|
||||
|
|
|
@ -97,7 +97,7 @@ template sendResponse(peer: Peer, proto, msg: untyped, data: varargs[untyped]):
|
|||
|
||||
asyncTest "network with 3 peers using custom protocols":
|
||||
const useCompression = defined(useSnappy)
|
||||
let localKeys = newKeyPair()
|
||||
let localKeys = KeyPair.random()[]
|
||||
let localAddress = localAddress(30303)
|
||||
var localNode = newEthereumNode(localKeys, localAddress, 1, nil, useCompression = useCompression)
|
||||
localNode.startListening()
|
||||
|
|
Loading…
Reference in New Issue