mirror of https://github.com/status-im/nim-eth.git
secp: requiresInit updates (#258)
* secp: requiresInit updates * fixup! * clean up mapconverts
This commit is contained in:
parent
5c6d8ccb36
commit
61feae0f21
|
@ -297,7 +297,7 @@ proc createKeyFileJson*(seckey: PrivateKey,
|
||||||
|
|
||||||
ok(%*
|
ok(%*
|
||||||
{
|
{
|
||||||
"address": (? seckey.toPublicKey().mapErrTo(IncorrectPrivateKey)).toAddress(false),
|
"address": seckey.toPublicKey().toAddress(false),
|
||||||
"crypto": {
|
"crypto": {
|
||||||
"cipher": $cryptkind,
|
"cipher": $cryptkind,
|
||||||
"cipherparams": {
|
"cipherparams": {
|
||||||
|
|
104
eth/keys.nim
104
eth/keys.nim
|
@ -53,22 +53,20 @@ type
|
||||||
proc random*(T: type PrivateKey): SkResult[T] =
|
proc random*(T: type PrivateKey): SkResult[T] =
|
||||||
SkSecretKey.random().mapConvert(T)
|
SkSecretKey.random().mapConvert(T)
|
||||||
|
|
||||||
proc fromRaw*(T: type PrivateKey, data: openArray[byte]): SkResult[T] =
|
func fromRaw*(T: type PrivateKey, data: openArray[byte]): SkResult[T] =
|
||||||
SkSecretKey.fromRaw(data).mapConvert(T)
|
SkSecretKey.fromRaw(data).mapConvert(T)
|
||||||
|
|
||||||
proc fromHex*(T: type PrivateKey, data: string): SkResult[T] =
|
func fromHex*(T: type PrivateKey, data: string): SkResult[T] =
|
||||||
SkSecretKey.fromHex(data).mapConvert(T)
|
SkSecretKey.fromHex(data).mapConvert(T)
|
||||||
|
|
||||||
proc toRaw*(seckey: PrivateKey): array[SkRawSecretKeySize, byte] {.borrow.}
|
func toRaw*(seckey: PrivateKey): array[SkRawSecretKeySize, byte] =
|
||||||
|
SkSecretKey(seckey).toRaw()
|
||||||
|
|
||||||
proc toPublicKey*(seckey: PrivateKey): SkResult[PublicKey] =
|
func toPublicKey*(seckey: PrivateKey): PublicKey {.borrow.}
|
||||||
SkSecretKey(seckey).toPublicKey().mapConvert(PublicKey)
|
|
||||||
|
|
||||||
proc verify*(seckey: PrivateKey): bool {.borrow.}
|
func fromRaw*(T: type PublicKey, data: openArray[byte]): SkResult[T] =
|
||||||
|
|
||||||
proc fromRaw*(T: type PublicKey, data: openArray[byte]): SkResult[T] =
|
|
||||||
if data.len() == SkRawCompressedPublicKeySize:
|
if data.len() == SkRawCompressedPublicKeySize:
|
||||||
return SkPublicKey.fromRaw(data).mapConvert(PublicKey)
|
return SkPublicKey.fromRaw(data).mapConvert(T)
|
||||||
|
|
||||||
if len(data) < SkRawPublicKeySize - 1:
|
if len(data) < SkRawPublicKeySize - 1:
|
||||||
return err(static(
|
return err(static(
|
||||||
|
@ -78,46 +76,44 @@ proc fromRaw*(T: type PublicKey, data: openArray[byte]): SkResult[T] =
|
||||||
d[0] = 0x04'u8
|
d[0] = 0x04'u8
|
||||||
copyMem(addr d[1], unsafeAddr data[0], 64)
|
copyMem(addr d[1], unsafeAddr data[0], 64)
|
||||||
|
|
||||||
SkPublicKey.fromRaw(d).mapConvert(PublicKey)
|
SkPublicKey.fromRaw(d).mapConvert(T)
|
||||||
|
|
||||||
proc fromHex*(T: type PublicKey, data: string): SkResult[T] =
|
func fromHex*(T: type PublicKey, data: string): SkResult[T] =
|
||||||
T.fromRaw(? seq[byte].fromHex(data))
|
T.fromRaw(? seq[byte].fromHex(data))
|
||||||
|
|
||||||
proc toRaw*(pubkey: PublicKey): array[RawPublicKeySize, byte] =
|
func toRaw*(pubkey: PublicKey): array[RawPublicKeySize, byte] =
|
||||||
let tmp = SkPublicKey(pubkey).toRaw()
|
let tmp = SkPublicKey(pubkey).toRaw()
|
||||||
copyMem(addr result[0], unsafeAddr tmp[1], 64)
|
copyMem(addr result[0], unsafeAddr tmp[1], 64)
|
||||||
|
|
||||||
proc toRawCompressed*(pubkey: PublicKey): array[33, byte] {.borrow.}
|
func toRawCompressed*(pubkey: PublicKey): array[33, byte] {.borrow.}
|
||||||
|
|
||||||
proc random*(T: type KeyPair): SkResult[T] =
|
proc random*(T: type KeyPair): SkResult[T] =
|
||||||
let tmp = ?SkKeypair.random()
|
let tmp = ? SkKeypair.random()
|
||||||
ok(T(seckey: PrivateKey(tmp.seckey), pubkey: PublicKey(tmp.pubkey)))
|
ok(T(seckey: PrivateKey(tmp.seckey), pubkey: PublicKey(tmp.pubkey)))
|
||||||
|
|
||||||
proc toKeyPair*(seckey: PrivateKey): SkResult[KeyPair] =
|
func toKeyPair*(seckey: PrivateKey): KeyPair =
|
||||||
let
|
KeyPair(seckey: seckey, pubkey: seckey.toPublicKey())
|
||||||
pubkey = seckey.toPublicKey()
|
|
||||||
pubkey and ok(KeyPair(seckey: seckey, pubkey: pubkey[]))
|
|
||||||
|
|
||||||
proc fromRaw*(T: type Signature, data: openArray[byte]): SkResult[T] =
|
func fromRaw*(T: type Signature, data: openArray[byte]): SkResult[T] =
|
||||||
SkRecoverableSignature.fromRaw(data).mapConvert(Signature)
|
SkRecoverableSignature.fromRaw(data).mapConvert(T)
|
||||||
|
|
||||||
proc fromHex*(T: type Signature, data: string): SkResult[T] =
|
func fromHex*(T: type Signature, data: string): SkResult[T] =
|
||||||
T.fromRaw(? seq[byte].fromHex(data))
|
T.fromRaw(? seq[byte].fromHex(data))
|
||||||
|
|
||||||
proc toRaw*(sig: Signature): array[RawSignatureSize, byte] {.borrow.}
|
func toRaw*(sig: Signature): array[RawSignatureSize, byte] {.borrow.}
|
||||||
|
|
||||||
proc fromRaw*(T: type SignatureNR, data: openArray[byte]): SkResult[T] =
|
func fromRaw*(T: type SignatureNR, data: openArray[byte]): SkResult[T] =
|
||||||
SkSignature.fromRaw(data).mapConvert(SignatureNR)
|
SkSignature.fromRaw(data).mapConvert(T)
|
||||||
|
|
||||||
proc toRaw*(sig: SignatureNR): array[RawSignatureNRSize, byte] {.borrow.}
|
func toRaw*(sig: SignatureNR): array[RawSignatureNRSize, byte] {.borrow.}
|
||||||
|
|
||||||
proc toAddress*(pubkey: PublicKey, with0x = true): string =
|
func toAddress*(pubkey: PublicKey, with0x = true): string =
|
||||||
## Convert public key to hexadecimal string address.
|
## Convert public key to hexadecimal string address.
|
||||||
var hash = keccak256.digest(pubkey.toRaw())
|
var hash = keccak256.digest(pubkey.toRaw())
|
||||||
result = if with0x: "0x" else: ""
|
result = if with0x: "0x" else: ""
|
||||||
result.add(toHex(toOpenArray(hash.data, 12, len(hash.data) - 1)))
|
result.add(toHex(toOpenArray(hash.data, 12, len(hash.data) - 1)))
|
||||||
|
|
||||||
proc toChecksumAddress*(pubkey: PublicKey, with0x = true): string =
|
func toChecksumAddress*(pubkey: PublicKey, with0x = true): string =
|
||||||
## Convert public key to checksumable mixed-case address (EIP-55).
|
## Convert public key to checksumable mixed-case address (EIP-55).
|
||||||
result = if with0x: "0x" else: ""
|
result = if with0x: "0x" else: ""
|
||||||
var hash1 = keccak256.digest(pubkey.toRaw())
|
var hash1 = keccak256.digest(pubkey.toRaw())
|
||||||
|
@ -134,7 +130,7 @@ proc toChecksumAddress*(pubkey: PublicKey, with0x = true): string =
|
||||||
let ch = chr(ord(hhash1[i]) - ord('a') + ord('A'))
|
let ch = chr(ord(hhash1[i]) - ord('a') + ord('A'))
|
||||||
result.add(ch)
|
result.add(ch)
|
||||||
|
|
||||||
proc validateChecksumAddress*(a: string): bool =
|
func validateChecksumAddress*(a: string): bool =
|
||||||
## Validate checksumable mixed-case address (EIP-55).
|
## Validate checksumable mixed-case address (EIP-55).
|
||||||
var address = ""
|
var address = ""
|
||||||
var check = "0x"
|
var check = "0x"
|
||||||
|
@ -180,54 +176,50 @@ func `$`*(seckey: PrivateKey): string =
|
||||||
## Convert private key to hexadecimal string representation
|
## Convert private key to hexadecimal string representation
|
||||||
toHex(seckey.toRaw())
|
toHex(seckey.toRaw())
|
||||||
|
|
||||||
proc `==`*(lhs, rhs: PublicKey): bool {.borrow.}
|
func `==`*(lhs, rhs: PublicKey): bool {.borrow.}
|
||||||
proc `==`*(lhs, rhs: Signature): bool {.borrow.}
|
func `==`*(lhs, rhs: Signature): bool {.borrow.}
|
||||||
proc `==`*(lhs, rhs: SignatureNR): bool {.borrow.}
|
func `==`*(lhs, rhs: SignatureNR): bool {.borrow.}
|
||||||
|
|
||||||
proc clear*(v: var PrivateKey) {.borrow.}
|
func clear*(v: var PrivateKey) {.borrow.}
|
||||||
proc clear*(v: var PublicKey) {.borrow.}
|
func clear*(v: var KeyPair) =
|
||||||
proc clear*(v: var Signature) {.borrow.}
|
|
||||||
proc clear*(v: var SignatureNR) {.borrow.}
|
|
||||||
proc clear*(v: var KeyPair) =
|
|
||||||
v.seckey.clear()
|
v.seckey.clear()
|
||||||
v.pubkey.clear()
|
|
||||||
|
|
||||||
proc clear*(v: var SharedSecret) = burnMem(v.data)
|
func clear*(v: var SharedSecret) = burnMem(v.data)
|
||||||
proc clear*(v: var SharedSecretFull) = burnMem(v.data)
|
func clear*(v: var SharedSecretFull) = burnMem(v.data)
|
||||||
|
|
||||||
proc sign*(seckey: PrivateKey, msg: SkMessage): SkResult[Signature] =
|
func sign*(seckey: PrivateKey, msg: SkMessage): Signature =
|
||||||
signRecoverable(SkSecretKey(seckey), msg).mapConvert(Signature)
|
Signature(signRecoverable(SkSecretKey(seckey), msg))
|
||||||
|
|
||||||
proc sign*(seckey: PrivateKey, msg: openArray[byte]): SkResult[Signature] =
|
func sign*(seckey: PrivateKey, msg: openArray[byte]): Signature =
|
||||||
let hash = keccak256.digest(msg)
|
let hash = keccak256.digest(msg)
|
||||||
sign(seckey, hash)
|
sign(seckey, hash)
|
||||||
|
|
||||||
proc signNR*(seckey: PrivateKey, msg: SkMessage): SkResult[SignatureNR] =
|
func signNR*(seckey: PrivateKey, msg: SkMessage): SignatureNR =
|
||||||
sign(SkSecretKey(seckey), msg).mapConvert(SignatureNR)
|
SignatureNR(sign(SkSecretKey(seckey), msg))
|
||||||
|
|
||||||
proc signNR*(seckey: PrivateKey, msg: openArray[byte]): SkResult[SignatureNR] =
|
func signNR*(seckey: PrivateKey, msg: openArray[byte]): SignatureNR =
|
||||||
let hash = keccak256.digest(msg)
|
let hash = keccak256.digest(msg)
|
||||||
signNR(seckey, hash)
|
signNR(seckey, hash)
|
||||||
|
|
||||||
proc recover*(sig: Signature, msg: SkMessage): SkResult[PublicKey] =
|
func recover*(sig: Signature, msg: SkMessage): SkResult[PublicKey] =
|
||||||
recover(SkRecoverableSignature(sig), msg).mapConvert(PublicKey)
|
recover(SkRecoverableSignature(sig), msg).mapConvert(PublicKey)
|
||||||
|
|
||||||
proc recover*(sig: Signature, msg: openArray[byte]): SkResult[PublicKey] =
|
func recover*(sig: Signature, msg: openArray[byte]): SkResult[PublicKey] =
|
||||||
let hash = keccak256.digest(msg)
|
let hash = keccak256.digest(msg)
|
||||||
recover(sig, hash)
|
recover(sig, hash)
|
||||||
|
|
||||||
proc verify*(sig: SignatureNR, msg: SkMessage, key: PublicKey): bool =
|
func verify*(sig: SignatureNR, msg: SkMessage, key: PublicKey): bool =
|
||||||
verify(SkSignature(sig), msg, SkPublicKey(key))
|
verify(SkSignature(sig), msg, SkPublicKey(key))
|
||||||
|
|
||||||
proc verify*(sig: SignatureNR, msg: openArray[byte], key: PublicKey): bool =
|
func verify*(sig: SignatureNR, msg: openArray[byte], key: PublicKey): bool =
|
||||||
let hash = keccak256.digest(msg)
|
let hash = keccak256.digest(msg)
|
||||||
verify(sig, hash, key)
|
verify(sig, hash, key)
|
||||||
|
|
||||||
proc ecdhRaw*(seckey: PrivateKey, pubkey: PublicKey): SkResult[SharedSecret] =
|
func ecdhRaw*(seckey: PrivateKey, pubkey: PublicKey): SharedSecret =
|
||||||
ecdhRaw(
|
let tmp = ecdhRaw(SkSecretKey(seckey), SkPublicKey(pubkey))
|
||||||
SkSecretKey(seckey), SkPublicKey(pubkey)).map proc(v: auto): SharedSecret =
|
|
||||||
# Remove first byte!
|
|
||||||
copyMem(addr result.data[0], unsafeAddr(v.data[1]), sizeof(result))
|
|
||||||
|
|
||||||
proc ecdhRawFull*(seckey: PrivateKey, pubkey: PublicKey): SkResult[SharedSecretFull] =
|
# Remove first byte!
|
||||||
ecdhRaw(SkSecretKey(seckey), SkPublicKey(pubkey)).mapconvert(SharedSecretFull)
|
copyMem(addr result.data[0], unsafeAddr(tmp.data[1]), sizeof(result))
|
||||||
|
|
||||||
|
func ecdhRawFull*(seckey: PrivateKey, pubkey: PublicKey): SharedSecretFull =
|
||||||
|
SharedSecretFull(ecdhRaw(SkSecretKey(seckey), SkPublicKey(pubkey)))
|
||||||
|
|
|
@ -136,13 +136,12 @@ proc authMessagePreEIP8(h: var Handshake,
|
||||||
outlen = 0
|
outlen = 0
|
||||||
let header = cast[ptr AuthMessageV4](addr buffer[0])
|
let header = cast[ptr AuthMessageV4](addr buffer[0])
|
||||||
|
|
||||||
var secret = ? ecdhRaw(h.host.seckey, pubkey).mapErrTo(EcdhError)
|
var secret = ecdhRaw(h.host.seckey, pubkey)
|
||||||
let xornonce = secret.data xor h.initiatorNonce
|
let xornonce = secret.data xor h.initiatorNonce
|
||||||
|
|
||||||
secret.clear()
|
secret.clear()
|
||||||
|
|
||||||
let signature = ? sign(
|
let signature = sign(h.ephemeral.seckey, SkMessage(data: xornonce))
|
||||||
h.ephemeral.seckey, SkMessage(data: xornonce)).mapErrTo(SignatureError)
|
|
||||||
|
|
||||||
h.remoteHPubkey = pubkey
|
h.remoteHPubkey = pubkey
|
||||||
header.signature = signature.toRaw()
|
header.signature = signature.toRaw()
|
||||||
|
@ -178,13 +177,12 @@ proc authMessageEIP8(h: var Handshake,
|
||||||
doAssert(EIP8 in h.flags)
|
doAssert(EIP8 in h.flags)
|
||||||
outlen = 0
|
outlen = 0
|
||||||
var
|
var
|
||||||
secret = ? ecdhRaw(h.host.seckey, pubkey).mapErrTo(EcdhError)
|
secret = ecdhRaw(h.host.seckey, pubkey)
|
||||||
xornonce = secret.data xor h.initiatorNonce
|
xornonce = secret.data xor h.initiatorNonce
|
||||||
|
|
||||||
secret.clear()
|
secret.clear()
|
||||||
|
|
||||||
let signature = ? sign(
|
let signature = sign(h.ephemeral.seckey, SkMessage(data: xornonce))
|
||||||
h.ephemeral.seckey, SkMessage(data: xornonce)).mapErrTo(SignatureError)
|
|
||||||
|
|
||||||
h.remoteHPubkey = pubkey
|
h.remoteHPubkey = pubkey
|
||||||
var payload = rlp.encodeList(signature.toRaw(),
|
var payload = rlp.encodeList(signature.toRaw(),
|
||||||
|
@ -348,7 +346,7 @@ proc decodeAuthMessageV4(h: var Handshake, m: openarray[byte]): AuthResult[void]
|
||||||
pubkey = ? PublicKey.fromRaw(header.pubkey).mapErrTo(InvalidPubKey)
|
pubkey = ? PublicKey.fromRaw(header.pubkey).mapErrTo(InvalidPubKey)
|
||||||
signature = ? Signature.fromRaw(header.signature).mapErrTo(SignatureError)
|
signature = ? Signature.fromRaw(header.signature).mapErrTo(SignatureError)
|
||||||
|
|
||||||
var secret = ? ecdhRaw(h.host.seckey, pubkey).mapErrTo(EcdhError)
|
var secret = ecdhRaw(h.host.seckey, pubkey)
|
||||||
let xornonce = secret.data xor header.nonce
|
let xornonce = secret.data xor header.nonce
|
||||||
|
|
||||||
secret.clear()
|
secret.clear()
|
||||||
|
@ -393,7 +391,7 @@ proc decodeAuthMessageEip8(h: var Handshake, m: openarray[byte]): AuthResult[voi
|
||||||
pubkey = ? PublicKey.fromRaw(pubkeyBr).mapErrTo(InvalidPubKey)
|
pubkey = ? PublicKey.fromRaw(pubkeyBr).mapErrTo(InvalidPubKey)
|
||||||
nonce = toArray(KeyLength, nonceBr)
|
nonce = toArray(KeyLength, nonceBr)
|
||||||
|
|
||||||
var secret = ? ecdhRaw(h.host.seckey, pubkey).mapErrTo(EcdhError)
|
var secret = ecdhRaw(h.host.seckey, pubkey)
|
||||||
|
|
||||||
let xornonce = nonce xor secret.data
|
let xornonce = nonce xor secret.data
|
||||||
secret.clear()
|
secret.clear()
|
||||||
|
@ -495,7 +493,7 @@ proc getSecrets*(
|
||||||
secret: ConnectionSecret
|
secret: ConnectionSecret
|
||||||
|
|
||||||
# ecdhe-secret = ecdh.agree(ephemeral-privkey, remote-ephemeral-pubk)
|
# ecdhe-secret = ecdh.agree(ephemeral-privkey, remote-ephemeral-pubk)
|
||||||
var shsec = ? ecdhRaw(h.ephemeral.seckey, h.remoteEPubkey).mapErrTo(EcdhError)
|
var shsec = ecdhRaw(h.ephemeral.seckey, h.remoteEPubkey)
|
||||||
|
|
||||||
# shared-secret = keccak(ecdhe-secret || keccak(nonce || initiator-nonce))
|
# shared-secret = keccak(ecdhe-secret || keccak(nonce || initiator-nonce))
|
||||||
ctx0.init()
|
ctx0.init()
|
||||||
|
|
|
@ -69,7 +69,7 @@ proc pack(cmdId: CommandId, payload: openArray[byte], pk: PrivateKey): seq[byte]
|
||||||
|
|
||||||
# TODO: There is a lot of unneeded allocations here
|
# TODO: There is a lot of unneeded allocations here
|
||||||
let encodedData = @[cmdId.byte] & @payload
|
let encodedData = @[cmdId.byte] & @payload
|
||||||
let signature = @(pk.sign(encodedData).tryGet().toRaw())
|
let signature = @(pk.sign(encodedData).toRaw())
|
||||||
let msgHash = keccak256.digest(signature & encodedData)
|
let msgHash = keccak256.digest(signature & encodedData)
|
||||||
result = @(msgHash.data) & signature & encodedData
|
result = @(msgHash.data) & signature & encodedData
|
||||||
|
|
||||||
|
@ -162,7 +162,7 @@ proc newDiscoveryProtocol*(privKey: PrivateKey, address: Address,
|
||||||
result.address = address
|
result.address = address
|
||||||
result.bootstrapNodes = newSeqOfCap[Node](bootstrapNodes.len)
|
result.bootstrapNodes = newSeqOfCap[Node](bootstrapNodes.len)
|
||||||
for n in bootstrapNodes: result.bootstrapNodes.add(newNode(n))
|
for n in bootstrapNodes: result.bootstrapNodes.add(newNode(n))
|
||||||
result.thisNode = newNode(privKey.toPublicKey().tryGet(), address)
|
result.thisNode = newNode(privKey.toPublicKey(), address)
|
||||||
result.kademlia = newKademliaProtocol(result.thisNode, result)
|
result.kademlia = newKademliaProtocol(result.thisNode, result)
|
||||||
|
|
||||||
proc recvPing(d: DiscoveryProtocol, node: Node,
|
proc recvPing(d: DiscoveryProtocol, node: Node,
|
||||||
|
|
|
@ -63,12 +63,12 @@ proc idNonceHash(nonce, ephkey: openarray[byte]): MDigest[256] =
|
||||||
ctx.finish()
|
ctx.finish()
|
||||||
|
|
||||||
proc signIDNonce*(privKey: PrivateKey, idNonce, ephKey: openarray[byte]):
|
proc signIDNonce*(privKey: PrivateKey, idNonce, ephKey: openarray[byte]):
|
||||||
Result[SignatureNR, cstring] =
|
SignatureNR =
|
||||||
signNR(privKey, idNonceHash(idNonce, ephKey))
|
signNR(privKey, idNonceHash(idNonce, ephKey))
|
||||||
|
|
||||||
proc deriveKeys(n1, n2: NodeID, priv: PrivateKey, pub: PublicKey,
|
proc deriveKeys(n1, n2: NodeID, priv: PrivateKey, pub: PublicKey,
|
||||||
idNonce: openarray[byte]): Result[HandshakeSecrets, cstring] =
|
idNonce: openarray[byte]): HandshakeSecrets =
|
||||||
let eph = ? ecdhRawFull(priv, pub)
|
let eph = ecdhRawFull(priv, pub)
|
||||||
|
|
||||||
var info = newSeqOfCap[byte](idNoncePrefix.len + 32 * 2)
|
var info = newSeqOfCap[byte](idNoncePrefix.len + 32 * 2)
|
||||||
for i, c in keyAgreementPrefix: info.add(byte(c))
|
for i, c in keyAgreementPrefix: info.add(byte(c))
|
||||||
|
@ -79,7 +79,7 @@ proc deriveKeys(n1, n2: NodeID, priv: PrivateKey, pub: PublicKey,
|
||||||
static: assert(sizeof(secrets) == aesKeySize * 3)
|
static: assert(sizeof(secrets) == aesKeySize * 3)
|
||||||
var res = cast[ptr UncheckedArray[byte]](addr secrets)
|
var res = cast[ptr UncheckedArray[byte]](addr secrets)
|
||||||
hkdf(sha256, eph.data, idNonce, info, toOpenArray(res, 0, sizeof(secrets) - 1))
|
hkdf(sha256, eph.data, idNonce, info, toOpenArray(res, 0, sizeof(secrets) - 1))
|
||||||
ok(secrets)
|
secrets
|
||||||
|
|
||||||
proc encryptGCM*(key, nonce, pt, authData: openarray[byte]): seq[byte] =
|
proc encryptGCM*(key, nonce, pt, authData: openarray[byte]): seq[byte] =
|
||||||
var ectx: GCM[aes128]
|
var ectx: GCM[aes128]
|
||||||
|
@ -102,11 +102,11 @@ proc encodeAuthHeader*(c: Codec,
|
||||||
resp.record = ln.record
|
resp.record = ln.record
|
||||||
|
|
||||||
let ephKeys = ? KeyPair.random()
|
let ephKeys = ? KeyPair.random()
|
||||||
let signature = ? signIDNonce(c.privKey, challenge.idNonce,
|
let signature = signIDNonce(c.privKey, challenge.idNonce,
|
||||||
ephKeys.pubkey.toRaw)
|
ephKeys.pubkey.toRaw)
|
||||||
resp.signature = signature.toRaw
|
resp.signature = signature.toRaw
|
||||||
|
|
||||||
let secrets = ? deriveKeys(ln.id, toId, ephKeys.seckey, challenge.pubKey,
|
let secrets = deriveKeys(ln.id, toId, ephKeys.seckey, challenge.pubKey,
|
||||||
challenge.idNonce)
|
challenge.idNonce)
|
||||||
|
|
||||||
let respRlp = rlp.encode(resp)
|
let respRlp = rlp.encode(resp)
|
||||||
|
@ -234,8 +234,8 @@ proc decodeAuthResp*(c: Codec, fromId: NodeId, head: AuthHeader,
|
||||||
|
|
||||||
let ephKey = ? PublicKey.fromRaw(head.ephemeralKey).mapErrTo(HandshakeError)
|
let ephKey = ? PublicKey.fromRaw(head.ephemeralKey).mapErrTo(HandshakeError)
|
||||||
|
|
||||||
let secrets = ? deriveKeys(fromId, c.localNode.id, c.privKey, ephKey,
|
let secrets =
|
||||||
challenge.idNonce).mapErrTo(HandshakeError)
|
deriveKeys(fromId, c.localNode.id, c.privKey, ephKey, challenge.idNonce)
|
||||||
|
|
||||||
var zeroNonce: array[gcmNonceSize, byte]
|
var zeroNonce: array[gcmNonceSize, byte]
|
||||||
let respData = decryptGCM(secrets.authRespKey, zeroNonce, head.response, [])
|
let respData = decryptGCM(secrets.authRespKey, zeroNonce, head.response, [])
|
||||||
|
|
|
@ -69,7 +69,7 @@ proc makeEnrAux(seqNum: uint64, pk: PrivateKey,
|
||||||
record.pairs = @pairs
|
record.pairs = @pairs
|
||||||
record.seqNum = seqNum
|
record.seqNum = seqNum
|
||||||
|
|
||||||
let pubkey = ? pk.toPublicKey()
|
let pubkey = pk.toPublicKey()
|
||||||
|
|
||||||
record.pairs.add(("id", Field(kind: kString, str: "v4")))
|
record.pairs.add(("id", Field(kind: kString, str: "v4")))
|
||||||
record.pairs.add(("secp256k1",
|
record.pairs.add(("secp256k1",
|
||||||
|
@ -94,7 +94,7 @@ proc makeEnrAux(seqNum: uint64, pk: PrivateKey,
|
||||||
var w = initRlpList(record.pairs.len * 2 + 1)
|
var w = initRlpList(record.pairs.len * 2 + 1)
|
||||||
w.append(seqNum, record.pairs)
|
w.append(seqNum, record.pairs)
|
||||||
|
|
||||||
let sig = ? signNR(pk, toSign)
|
let sig = signNR(pk, toSign)
|
||||||
|
|
||||||
record.raw = block:
|
record.raw = block:
|
||||||
var w = initRlpList(record.pairs.len * 2 + 2)
|
var w = initRlpList(record.pairs.len * 2 + 2)
|
||||||
|
|
|
@ -115,7 +115,7 @@ proc eciesEncrypt*(input: openarray[byte], output: var openarray[byte],
|
||||||
|
|
||||||
var
|
var
|
||||||
ephemeral = ? KeyPair.random().mapErrTo(RandomError)
|
ephemeral = ? KeyPair.random().mapErrTo(RandomError)
|
||||||
secret = ? ecdhRaw(ephemeral.seckey, pubkey).mapErrTo(EcdhError)
|
secret = ecdhRaw(ephemeral.seckey, pubkey)
|
||||||
material = kdf(secret.data)
|
material = kdf(secret.data)
|
||||||
|
|
||||||
clear(secret)
|
clear(secret)
|
||||||
|
@ -184,7 +184,7 @@ proc eciesDecrypt*(input: openarray[byte],
|
||||||
|
|
||||||
var
|
var
|
||||||
pubkey = ? PublicKey.fromRaw(header.pubkey).mapErrTo(IncorrectKey)
|
pubkey = ? PublicKey.fromRaw(header.pubkey).mapErrTo(IncorrectKey)
|
||||||
secret = ? ecdhRaw(seckey, pubkey).mapErrTo(EcdhError)
|
secret = ecdhRaw(seckey, pubkey)
|
||||||
|
|
||||||
var material = kdf(secret.data)
|
var material = kdf(secret.data)
|
||||||
burnMem(secret)
|
burnMem(secret)
|
||||||
|
|
|
@ -292,11 +292,8 @@ proc encode*(self: Payload): Option[seq[byte]] =
|
||||||
|
|
||||||
if self.src.isSome(): # Private key present - signature requested
|
if self.src.isSome(): # Private key present - signature requested
|
||||||
let sig = sign(self.src.get(), plain)
|
let sig = sign(self.src.get(), plain)
|
||||||
if sig.isErr:
|
|
||||||
notice "Signing message failed", err = sig.error
|
|
||||||
return
|
|
||||||
|
|
||||||
plain.add sig[].toRaw()
|
plain.add sig.toRaw()
|
||||||
|
|
||||||
if self.dst.isSome(): # Asymmetric key present - encryption requested
|
if self.dst.isSome(): # Asymmetric key present - encryption requested
|
||||||
var res = newSeq[byte](eciesEncryptedLength(plain.len))
|
var res = newSeq[byte](eciesEncryptedLength(plain.len))
|
||||||
|
@ -626,7 +623,7 @@ proc notify*(filters: var Filters, msg: Message) {.gcsafe.} =
|
||||||
if filter.privateKey.isSome():
|
if filter.privateKey.isSome():
|
||||||
keyHash = keccak256.digest(filter.privateKey.get().toRaw())
|
keyHash = keccak256.digest(filter.privateKey.get().toRaw())
|
||||||
# TODO: Get rid of the hash and just use pubkey to compare?
|
# TODO: Get rid of the hash and just use pubkey to compare?
|
||||||
dst = some(toPublicKey(filter.privateKey.get()).tryGet())
|
dst = some(toPublicKey(filter.privateKey.get()))
|
||||||
elif filter.symKey.isSome():
|
elif filter.symKey.isSome():
|
||||||
keyHash = keccak256.digest(filter.symKey.get())
|
keyHash = keccak256.digest(filter.symKey.get())
|
||||||
# else:
|
# else:
|
||||||
|
|
|
@ -56,22 +56,22 @@ suite "ECC/ECDSA/ECDHE tests suite":
|
||||||
test "Known private to known public keys (test data from Ethereum eth-keys)":
|
test "Known private to known public keys (test data from Ethereum eth-keys)":
|
||||||
for person in [alice, bob, eve]:
|
for person in [alice, bob, eve]:
|
||||||
let privkey = PrivateKey.fromHex(person[0])[]
|
let privkey = PrivateKey.fromHex(person[0])[]
|
||||||
var pubkeyHex = $privkey.toPublicKey()[]
|
var pubkeyHex = $privkey.toPublicKey()
|
||||||
check:
|
check:
|
||||||
pubkeyHex == stripSpaces(person[1])
|
pubkeyHex == stripSpaces(person[1])
|
||||||
|
|
||||||
test "Recover public key from message":
|
test "Recover public key from message":
|
||||||
for person in [alice, bob, eve]:
|
for person in [alice, bob, eve]:
|
||||||
let privkey = PrivateKey.fromHex(person[0])[]
|
let privkey = PrivateKey.fromHex(person[0])[]
|
||||||
let signature = privkey.sign(message)[]
|
let signature = privkey.sign(message)
|
||||||
let recoveredKey = signature.recover(message)[]
|
let recoveredKey = signature.recover(message)[]
|
||||||
check:
|
check:
|
||||||
$privkey.toPublicKey()[] == $recoveredKey
|
$privkey.toPublicKey() == $recoveredKey
|
||||||
|
|
||||||
test "Signature serialization and deserialization":
|
test "Signature serialization and deserialization":
|
||||||
for person in [alice, bob, eve]:
|
for person in [alice, bob, eve]:
|
||||||
let privkey = PrivateKey.fromHex(person[0])[]
|
let privkey = PrivateKey.fromHex(person[0])[]
|
||||||
let signature = privkey.sign(message)[]
|
let signature = privkey.sign(message)
|
||||||
let expectSignature = Signature.fromHex(stripSpaces(person[2]))[]
|
let expectSignature = Signature.fromHex(stripSpaces(person[2]))[]
|
||||||
check:
|
check:
|
||||||
$signature == $expectSignature
|
$signature == $expectSignature
|
||||||
|
@ -79,26 +79,26 @@ suite "ECC/ECDSA/ECDHE tests suite":
|
||||||
test "test_recover_from_signature_obj":
|
test "test_recover_from_signature_obj":
|
||||||
var s = PrivateKey.fromHex(pkbytes)[]
|
var s = PrivateKey.fromHex(pkbytes)[]
|
||||||
var mhash = keccak256.digest(message)
|
var mhash = keccak256.digest(message)
|
||||||
var signature = s.sign(message)[]
|
var signature = s.sign(message)
|
||||||
var p = recover(signature, mhash)
|
var p = recover(signature, mhash)[]
|
||||||
check:
|
check:
|
||||||
s.toPublicKey() == p
|
s.toPublicKey() == p
|
||||||
|
|
||||||
test "test_to_address_from_public_key":
|
test "test_to_address_from_public_key":
|
||||||
var s = PrivateKey.fromHex(pkbytes)[]
|
var s = PrivateKey.fromHex(pkbytes)[]
|
||||||
var chk = s.toPublicKey()[].toAddress()
|
var chk = s.toPublicKey().toAddress()
|
||||||
var expect = "0x" & address
|
var expect = "0x" & address
|
||||||
check chk == expect
|
check chk == expect
|
||||||
|
|
||||||
test "test_to_canonical_address_from_public_key":
|
test "test_to_canonical_address_from_public_key":
|
||||||
var s = PrivateKey.fromHex(pkbytes)[]
|
var s = PrivateKey.fromHex(pkbytes)[]
|
||||||
var chk = s.toPublicKey()[].toCanonicalAddress()
|
var chk = s.toPublicKey().toCanonicalAddress()
|
||||||
var expect = fromHex(stripSpaces(address))
|
var expect = fromHex(stripSpaces(address))
|
||||||
check compare(chk, expect) == true
|
check compare(chk, expect) == true
|
||||||
|
|
||||||
test "test_to_checksum_address_from_public_key":
|
test "test_to_checksum_address_from_public_key":
|
||||||
var s = PrivateKey.fromHex(pkbytes)[]
|
var s = PrivateKey.fromHex(pkbytes)[]
|
||||||
var chk = s.toPublicKey()[].toChecksumAddress()
|
var chk = s.toPublicKey().toChecksumAddress()
|
||||||
var expect = "0x" & address
|
var expect = "0x" & address
|
||||||
check:
|
check:
|
||||||
chk.toLowerAscii() == expect
|
chk.toLowerAscii() == expect
|
||||||
|
@ -159,7 +159,7 @@ suite "ECC/ECDSA/ECDHE tests suite":
|
||||||
var s = PrivateKey.fromHex(privateKeys[i])[]
|
var s = PrivateKey.fromHex(privateKeys[i])[]
|
||||||
var p = PublicKey.fromHex(stripSpaces(publicKeys[i]))[]
|
var p = PublicKey.fromHex(stripSpaces(publicKeys[i]))[]
|
||||||
let expect = fromHex(stripSpaces(sharedSecrets[i]))
|
let expect = fromHex(stripSpaces(sharedSecrets[i]))
|
||||||
let secret = ecdhRaw(s, p)[]
|
let secret = ecdhRaw(s, p)
|
||||||
check:
|
check:
|
||||||
expect == secret.data
|
expect == secret.data
|
||||||
|
|
||||||
|
@ -169,9 +169,9 @@ suite "ECC/ECDSA/ECDHE tests suite":
|
||||||
var expectm = """
|
var expectm = """
|
||||||
8ac7e464348b85d9fdfc0a81f2fdc0bbbb8ee5fb3840de6ed60ad9372e718977"""
|
8ac7e464348b85d9fdfc0a81f2fdc0bbbb8ee5fb3840de6ed60ad9372e718977"""
|
||||||
var s = PrivateKey.fromRaw(keccak256.digest("ecdhAgree").data)[]
|
var s = PrivateKey.fromRaw(keccak256.digest("ecdhAgree").data)[]
|
||||||
var p = s.toPublicKey()[]
|
var p = s.toPublicKey()
|
||||||
let expect = fromHex(stripSpaces(expectm))
|
let expect = fromHex(stripSpaces(expectm))
|
||||||
let secret = ecdhRaw(s, p)[]
|
let secret = ecdhRaw(s, p)
|
||||||
check:
|
check:
|
||||||
expect == secret.data
|
expect == secret.data
|
||||||
|
|
||||||
|
@ -188,7 +188,7 @@ suite "ECC/ECDSA/ECDHE tests suite":
|
||||||
var s = PrivateKey.fromHex(stripSpaces(s0))[]
|
var s = PrivateKey.fromHex(stripSpaces(s0))[]
|
||||||
var p = PublicKey.fromHex(stripSpaces(p0))[]
|
var p = PublicKey.fromHex(stripSpaces(p0))[]
|
||||||
let expect = fromHex(stripSpaces(e0))
|
let expect = fromHex(stripSpaces(e0))
|
||||||
let secret = ecdhRaw(s, p)[]
|
let secret = ecdhRaw(s, p)
|
||||||
check:
|
check:
|
||||||
compare(expect, secret.data) == true
|
compare(expect, secret.data) == true
|
||||||
|
|
||||||
|
@ -206,7 +206,7 @@ suite "ECC/ECDSA/ECDHE tests suite":
|
||||||
|
|
||||||
var s = PrivateKey.fromRaw(keccak256.digest("sec").data)[]
|
var s = PrivateKey.fromRaw(keccak256.digest("sec").data)[]
|
||||||
var m = keccak256.digest("msg")
|
var m = keccak256.digest("msg")
|
||||||
var sig = sign(s, m)[]
|
var sig = sign(s, m)
|
||||||
var sersig = sig.toRaw()
|
var sersig = sig.toRaw()
|
||||||
var key = recover(sig, m)[]
|
var key = recover(sig, m)[]
|
||||||
var serkey = key.toRaw()
|
var serkey = key.toRaw()
|
||||||
|
@ -219,8 +219,8 @@ suite "ECC/ECDSA/ECDHE tests suite":
|
||||||
for i in 1..100:
|
for i in 1..100:
|
||||||
var m = PrivateKey.random()[].toRaw
|
var m = PrivateKey.random()[].toRaw
|
||||||
var s = PrivateKey.random()[]
|
var s = PrivateKey.random()[]
|
||||||
var key = s.toPublicKey()[]
|
var key = s.toPublicKey()
|
||||||
let sig = sign(s, m)[]
|
let sig = sign(s, m)
|
||||||
let rkey = recover(sig, m)[]
|
let rkey = recover(sig, m)[]
|
||||||
check:
|
check:
|
||||||
key == rkey
|
key == rkey
|
||||||
|
@ -229,7 +229,7 @@ suite "ECC/ECDSA/ECDHE tests suite":
|
||||||
# key create/recovery test
|
# key create/recovery test
|
||||||
for i in 1..100:
|
for i in 1..100:
|
||||||
var s = PrivateKey.random()[]
|
var s = PrivateKey.random()[]
|
||||||
var key = s.toPublicKey()[]
|
var key = s.toPublicKey()
|
||||||
let rkey = PublicKey.fromRaw(key.toRaw())[]
|
let rkey = PublicKey.fromRaw(key.toRaw())[]
|
||||||
check:
|
check:
|
||||||
key == rkey
|
key == rkey
|
||||||
|
@ -238,22 +238,14 @@ suite "ECC/ECDSA/ECDHE tests suite":
|
||||||
# ECDHE shared secret test
|
# ECDHE shared secret test
|
||||||
for i in 1..100:
|
for i in 1..100:
|
||||||
var aliceSecret = PrivateKey.random()[]
|
var aliceSecret = PrivateKey.random()[]
|
||||||
var alicePublic = aliceSecret.toPublicKey()[]
|
var alicePublic = aliceSecret.toPublicKey()
|
||||||
var bobSecret = PrivateKey.random()[]
|
var bobSecret = PrivateKey.random()[]
|
||||||
var bobPublic = bobSecret.toPublicKey()[]
|
var bobPublic = bobSecret.toPublicKey()
|
||||||
var secret1 = ecdhRaw(aliceSecret, bobPublic)[]
|
var secret1 = ecdhRaw(aliceSecret, bobPublic)
|
||||||
var secret2 = ecdhRaw(bobSecret, alicePublic)[]
|
var secret2 = ecdhRaw(bobSecret, alicePublic)
|
||||||
check:
|
check:
|
||||||
secret1 == secret2
|
secret1 == secret2
|
||||||
|
|
||||||
test "verfiy() checks":
|
|
||||||
var seckey1: PrivateKey
|
|
||||||
var seckey2 = PrivateKey.random()[]
|
|
||||||
|
|
||||||
check:
|
|
||||||
seckey1.verify() == false
|
|
||||||
seckey2.verify() == true
|
|
||||||
|
|
||||||
test "Compressed public keys":
|
test "Compressed public keys":
|
||||||
let pubkeyCompressed = "03CA634CAE0D49ACB401D8A4C6B6FE8C55B70D115BF400769CC1400F3258CD3138".toLowerAscii
|
let pubkeyCompressed = "03CA634CAE0D49ACB401D8A4C6B6FE8C55B70D115BF400769CC1400F3258CD3138".toLowerAscii
|
||||||
let s = PublicKey.fromHex(pubkeyCompressed)[]
|
let s = PublicKey.fromHex(pubkeyCompressed)[]
|
||||||
|
|
|
@ -19,7 +19,7 @@ suite "Testing private -> public key conversion":
|
||||||
for person in [alice, bob, eve]:
|
for person in [alice, bob, eve]:
|
||||||
let
|
let
|
||||||
privKey = PrivateKey.fromHex(person.privkey)[]
|
privKey = PrivateKey.fromHex(person.privkey)[]
|
||||||
pubKey = privKey.toPublicKey()[]
|
pubKey = privKey.toPublicKey()
|
||||||
|
|
||||||
check:
|
check:
|
||||||
# Compare as strings
|
# Compare as strings
|
||||||
|
|
|
@ -45,7 +45,7 @@ template procSuite*(name, body: untyped) =
|
||||||
proc packData*(payload: openArray[byte], pk: PrivateKey): seq[byte] =
|
proc packData*(payload: openArray[byte], pk: PrivateKey): seq[byte] =
|
||||||
let
|
let
|
||||||
payloadSeq = @payload
|
payloadSeq = @payload
|
||||||
signature = @(pk.sign(payload).tryGet().toRaw())
|
signature = @(pk.sign(payload).toRaw())
|
||||||
msgHash = keccak256.digest(signature & payloadSeq)
|
msgHash = keccak256.digest(signature & payloadSeq)
|
||||||
result = @(msgHash.data) & signature & payloadSeq
|
result = @(msgHash.data) & signature & payloadSeq
|
||||||
|
|
||||||
|
|
|
@ -217,21 +217,21 @@ suite "Ethereum P2P handshake test suite":
|
||||||
proc newTestHandshake(flags: set[HandshakeFlag]): Handshake =
|
proc newTestHandshake(flags: set[HandshakeFlag]): Handshake =
|
||||||
if Initiator in flags:
|
if Initiator in flags:
|
||||||
let pk = PrivateKey.fromHex(testValue("initiator_private_key"))[]
|
let pk = PrivateKey.fromHex(testValue("initiator_private_key"))[]
|
||||||
let kp = KeyPair(seckey: pk, pubkey: pk.toPublicKey()[])
|
let kp = KeyPair(seckey: pk, pubkey: pk.toPublicKey())
|
||||||
result = Handshake.tryInit(kp, flags)[]
|
result = Handshake.tryInit(kp, flags)[]
|
||||||
|
|
||||||
let epki = testValue("initiator_ephemeral_private_key")
|
let epki = testValue("initiator_ephemeral_private_key")
|
||||||
result.ephemeral.seckey = PrivateKey.fromHex(epki)[]
|
result.ephemeral.seckey = PrivateKey.fromHex(epki)[]
|
||||||
result.ephemeral.pubkey = result.ephemeral.seckey.toPublicKey()[]
|
result.ephemeral.pubkey = result.ephemeral.seckey.toPublicKey()
|
||||||
let nonce = fromHex(stripSpaces(testValue("initiator_nonce")))
|
let nonce = fromHex(stripSpaces(testValue("initiator_nonce")))
|
||||||
result.initiatorNonce[0..^1] = nonce[0..^1]
|
result.initiatorNonce[0..^1] = nonce[0..^1]
|
||||||
elif Responder in flags:
|
elif Responder in flags:
|
||||||
let pk = PrivateKey.fromHex(testValue("receiver_private_key"))[]
|
let pk = PrivateKey.fromHex(testValue("receiver_private_key"))[]
|
||||||
let kp = KeyPair(seckey: pk, pubkey: pk.toPublicKey()[])
|
let kp = KeyPair(seckey: pk, pubkey: pk.toPublicKey())
|
||||||
result = Handshake.tryInit(kp, flags)[]
|
result = Handshake.tryInit(kp, flags)[]
|
||||||
let epkr = testValue("receiver_ephemeral_private_key")
|
let epkr = testValue("receiver_ephemeral_private_key")
|
||||||
result.ephemeral.seckey = PrivateKey.fromHex(epkr)[]
|
result.ephemeral.seckey = PrivateKey.fromHex(epkr)[]
|
||||||
result.ephemeral.pubkey = result.ephemeral.seckey.toPublicKey()[]
|
result.ephemeral.pubkey = result.ephemeral.seckey.toPublicKey()
|
||||||
let nonce = fromHex(stripSpaces(testValue("receiver_nonce")))
|
let nonce = fromHex(stripSpaces(testValue("receiver_nonce")))
|
||||||
result.responderNonce[0..^1] = nonce[0..^1]
|
result.responderNonce[0..^1] = nonce[0..^1]
|
||||||
|
|
||||||
|
@ -333,23 +333,23 @@ suite "Ethereum P2P handshake test suite":
|
||||||
proc newTestHandshake(flags: set[HandshakeFlag]): Handshake =
|
proc newTestHandshake(flags: set[HandshakeFlag]): Handshake =
|
||||||
if Initiator in flags:
|
if Initiator in flags:
|
||||||
let pk = PrivateKey.fromHex(testE8Value("initiator_private_key"))[]
|
let pk = PrivateKey.fromHex(testE8Value("initiator_private_key"))[]
|
||||||
let kp = KeyPair(seckey: pk, pubkey: pk.toPublicKey()[])
|
let kp = KeyPair(seckey: pk, pubkey: pk.toPublicKey())
|
||||||
result = Handshake.tryInit(kp, flags)[]
|
result = Handshake.tryInit(kp, flags)[]
|
||||||
|
|
||||||
result.host.pubkey = result.host.seckey.toPublicKey()[]
|
result.host.pubkey = result.host.seckey.toPublicKey()
|
||||||
let esec = testE8Value("initiator_ephemeral_private_key")
|
let esec = testE8Value("initiator_ephemeral_private_key")
|
||||||
result.ephemeral.seckey = PrivateKey.fromHex(esec)[]
|
result.ephemeral.seckey = PrivateKey.fromHex(esec)[]
|
||||||
result.ephemeral.pubkey = result.ephemeral.seckey.toPublicKey()[]
|
result.ephemeral.pubkey = result.ephemeral.seckey.toPublicKey()
|
||||||
let nonce = fromHex(stripSpaces(testE8Value("initiator_nonce")))
|
let nonce = fromHex(stripSpaces(testE8Value("initiator_nonce")))
|
||||||
result.initiatorNonce[0..^1] = nonce[0..^1]
|
result.initiatorNonce[0..^1] = nonce[0..^1]
|
||||||
elif Responder in flags:
|
elif Responder in flags:
|
||||||
let pk = PrivateKey.fromHex(testE8Value("receiver_private_key"))[]
|
let pk = PrivateKey.fromHex(testE8Value("receiver_private_key"))[]
|
||||||
let kp = KeyPair(seckey: pk, pubkey: pk.toPublicKey()[])
|
let kp = KeyPair(seckey: pk, pubkey: pk.toPublicKey())
|
||||||
result = Handshake.tryInit(kp, flags)[]
|
result = Handshake.tryInit(kp, flags)[]
|
||||||
|
|
||||||
let esec = testE8Value("receiver_ephemeral_private_key")
|
let esec = testE8Value("receiver_ephemeral_private_key")
|
||||||
result.ephemeral.seckey = PrivateKey.fromHex(esec)[]
|
result.ephemeral.seckey = PrivateKey.fromHex(esec)[]
|
||||||
result.ephemeral.pubkey = result.ephemeral.seckey.toPublicKey()[]
|
result.ephemeral.pubkey = result.ephemeral.seckey.toPublicKey()
|
||||||
let nonce = fromHex(stripSpaces(testE8Value("receiver_nonce")))
|
let nonce = fromHex(stripSpaces(testE8Value("receiver_nonce")))
|
||||||
result.responderNonce[0..^1] = nonce[0..^1]
|
result.responderNonce[0..^1] = nonce[0..^1]
|
||||||
|
|
||||||
|
|
|
@ -90,20 +90,20 @@ suite "Ethereum RLPx encryption/decryption test suite":
|
||||||
proc newTestHandshake(flags: set[HandshakeFlag]): Handshake =
|
proc newTestHandshake(flags: set[HandshakeFlag]): Handshake =
|
||||||
if Initiator in flags:
|
if Initiator in flags:
|
||||||
let pk = PrivateKey.fromHex(testValue("initiator_private_key"))[]
|
let pk = PrivateKey.fromHex(testValue("initiator_private_key"))[]
|
||||||
let kp = KeyPair(seckey: pk, pubkey: pk.toPublicKey()[])
|
let kp = KeyPair(seckey: pk, pubkey: pk.toPublicKey())
|
||||||
result = Handshake.tryInit(kp, flags)[]
|
result = Handshake.tryInit(kp, flags)[]
|
||||||
let epki = testValue("initiator_ephemeral_private_key")
|
let epki = testValue("initiator_ephemeral_private_key")
|
||||||
result.ephemeral.seckey = PrivateKey.fromHex(epki)[]
|
result.ephemeral.seckey = PrivateKey.fromHex(epki)[]
|
||||||
result.ephemeral.pubkey = result.ephemeral.seckey.toPublicKey()[]
|
result.ephemeral.pubkey = result.ephemeral.seckey.toPublicKey()
|
||||||
let nonce = fromHex(stripSpaces(testValue("initiator_nonce")))
|
let nonce = fromHex(stripSpaces(testValue("initiator_nonce")))
|
||||||
result.initiatorNonce[0..^1] = nonce[0..^1]
|
result.initiatorNonce[0..^1] = nonce[0..^1]
|
||||||
elif Responder in flags:
|
elif Responder in flags:
|
||||||
let pk = PrivateKey.fromHex(testValue("receiver_private_key"))[]
|
let pk = PrivateKey.fromHex(testValue("receiver_private_key"))[]
|
||||||
let kp = KeyPair(seckey: pk, pubkey: pk.toPublicKey()[])
|
let kp = KeyPair(seckey: pk, pubkey: pk.toPublicKey())
|
||||||
result = Handshake.tryInit(kp, flags)[]
|
result = Handshake.tryInit(kp, flags)[]
|
||||||
let epkr = testValue("receiver_ephemeral_private_key")
|
let epkr = testValue("receiver_ephemeral_private_key")
|
||||||
result.ephemeral.seckey = PrivateKey.fromHex(epkr)[]
|
result.ephemeral.seckey = PrivateKey.fromHex(epkr)[]
|
||||||
result.ephemeral.pubkey = result.ephemeral.seckey.toPublicKey()[]
|
result.ephemeral.pubkey = result.ephemeral.seckey.toPublicKey()
|
||||||
let nonce = fromHex(stripSpaces(testValue("receiver_nonce")))
|
let nonce = fromHex(stripSpaces(testValue("receiver_nonce")))
|
||||||
result.responderNonce[0..^1] = nonce[0..^1]
|
result.responderNonce[0..^1] = nonce[0..^1]
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ proc test() {.async.} =
|
||||||
bootNodeKey = PrivateKey.fromHex(
|
bootNodeKey = PrivateKey.fromHex(
|
||||||
"a2b50376a79b1a8c8a3296485572bdfbf54708bb46d3c25d73d2723aaaf6a617")[]
|
"a2b50376a79b1a8c8a3296485572bdfbf54708bb46d3c25d73d2723aaaf6a617")[]
|
||||||
bootNodeAddr = localAddress(20301)
|
bootNodeAddr = localAddress(20301)
|
||||||
bootENode = ENode(pubkey: bootNodeKey.toPublicKey()[], address: bootNodeAddr)
|
bootENode = ENode(pubkey: bootNodeKey.toPublicKey(), address: bootNodeAddr)
|
||||||
bootNode = await startDiscoveryNode(bootNodeKey, bootNodeAddr, @[])
|
bootNode = await startDiscoveryNode(bootNodeKey, bootNodeAddr, @[])
|
||||||
|
|
||||||
test "Discover nodes":
|
test "Discover nodes":
|
||||||
|
|
|
@ -183,7 +183,7 @@ suite "Discovery v5 Tests":
|
||||||
let targetId = toNodeId(PublicKey.fromHex(targetKey)[])
|
let targetId = toNodeId(PublicKey.fromHex(targetKey)[])
|
||||||
|
|
||||||
for (key, d) in testValues:
|
for (key, d) in testValues:
|
||||||
let id = toNodeId(PrivateKey.fromHex(key)[].toPublicKey()[])
|
let id = toNodeId(PrivateKey.fromHex(key)[].toPublicKey())
|
||||||
check logDist(targetId, id) == d
|
check logDist(targetId, id) == d
|
||||||
|
|
||||||
test "Distance to id check":
|
test "Distance to id check":
|
||||||
|
|
|
@ -136,8 +136,7 @@ suite "Discovery v5 Cryptographic Primitives":
|
||||||
priv = PrivateKey.fromHex(secretKey)[]
|
priv = PrivateKey.fromHex(secretKey)[]
|
||||||
let eph = ecdhRawFull(priv, pub)
|
let eph = ecdhRawFull(priv, pub)
|
||||||
check:
|
check:
|
||||||
eph.isOk()
|
eph.data == hexToSeqByte(sharedSecret)
|
||||||
eph[].data == hexToSeqByte(sharedSecret)
|
|
||||||
|
|
||||||
test "Key Derivation":
|
test "Key Derivation":
|
||||||
# const
|
# const
|
||||||
|
@ -169,8 +168,7 @@ suite "Discovery v5 Cryptographic Primitives":
|
||||||
privKey = PrivateKey.fromHex(localSecretKey)[]
|
privKey = PrivateKey.fromHex(localSecretKey)[]
|
||||||
signature = signIDNonce(privKey, hexToByteArray[idNonceSize](idNonce),
|
signature = signIDNonce(privKey, hexToByteArray[idNonceSize](idNonce),
|
||||||
hexToByteArray[64](ephemeralKey))
|
hexToByteArray[64](ephemeralKey))
|
||||||
check signature.isOK()
|
check signature.toRaw() == hexToByteArray[64](idNonceSig)
|
||||||
check signature[].toRaw() == hexToByteArray[64](idNonceSig)
|
|
||||||
|
|
||||||
test "Encryption/Decryption":
|
test "Encryption/Decryption":
|
||||||
const
|
const
|
||||||
|
@ -237,7 +235,7 @@ suite "Discovery v5 Additional":
|
||||||
Port(9000)).expect("Properly intialized private key")
|
Port(9000)).expect("Properly intialized private key")
|
||||||
node = newNode(enrRec).expect("Properly initialized record")
|
node = newNode(enrRec).expect("Properly initialized record")
|
||||||
nonce = hexToByteArray[authTagSize]("0x27b5af763c446acd2749fe8e")
|
nonce = hexToByteArray[authTagSize]("0x27b5af763c446acd2749fe8e")
|
||||||
pubKey = PrivateKey.random()[].toPublicKey()[]
|
pubKey = PrivateKey.random()[].toPublicKey()
|
||||||
nodeId = pubKey.toNodeId()
|
nodeId = pubKey.toNodeId()
|
||||||
idNonce = hexToByteArray[idNonceSize](
|
idNonce = hexToByteArray[idNonceSize](
|
||||||
"0xa77e3aa0c144ae7c0a3af73692b7d6e5b7a2fdc0eda16e8d5e6cb0d08e88dd04")
|
"0xa77e3aa0c144ae7c0a3af73692b7d6e5b7a2fdc0eda16e8d5e6cb0d08e88dd04")
|
||||||
|
@ -248,7 +246,7 @@ suite "Discovery v5 Additional":
|
||||||
var rlp = rlpFromBytes(auth)
|
var rlp = rlpFromBytes(auth)
|
||||||
let authHeader = rlp.read(AuthHeader)
|
let authHeader = rlp.read(AuthHeader)
|
||||||
var newNode: Node
|
var newNode: Node
|
||||||
let secrets = c.decodeAuthResp(privKey.toPublicKey()[].toNodeId(),
|
let secrets = c.decodeAuthResp(privKey.toPublicKey().toNodeId(),
|
||||||
authHeader, whoareyou, newNode)
|
authHeader, whoareyou, newNode)
|
||||||
|
|
||||||
# TODO: Test cases with invalid nodeId and invalid signature, the latter
|
# TODO: Test cases with invalid nodeId and invalid signature, the latter
|
||||||
|
|
|
@ -70,7 +70,7 @@ suite "ECIES test suite":
|
||||||
var decr = newSeq[byte](len(m))
|
var decr = newSeq[byte](len(m))
|
||||||
var shmac = [0x13'u8, 0x13'u8]
|
var shmac = [0x13'u8, 0x13'u8]
|
||||||
var s = PrivateKey.random()[]
|
var s = PrivateKey.random()[]
|
||||||
var p = s.toPublicKey()[]
|
var p = s.toPublicKey()
|
||||||
|
|
||||||
eciesEncrypt(plain, encr, p).expect("encryption should succeed")
|
eciesEncrypt(plain, encr, p).expect("encryption should succeed")
|
||||||
eciesDecrypt(encr, decr, s).expect("decryption should succeed")
|
eciesDecrypt(encr, decr, s).expect("decryption should succeed")
|
||||||
|
|
|
@ -45,13 +45,13 @@ suite "Whisper payload":
|
||||||
check:
|
check:
|
||||||
decoded.isSome()
|
decoded.isSome()
|
||||||
payload.payload == decoded.get().payload
|
payload.payload == decoded.get().payload
|
||||||
privKey.toPublicKey()[] == decoded.get().src.get()
|
privKey.toPublicKey() == decoded.get().src.get()
|
||||||
decoded.get().padding.get().len == 186 # 256 -1 -1 -3 -65
|
decoded.get().padding.get().len == 186 # 256 -1 -1 -3 -65
|
||||||
|
|
||||||
test "should roundtrip with asymmetric encryption":
|
test "should roundtrip with asymmetric encryption":
|
||||||
let privKey = PrivateKey.random()[]
|
let privKey = PrivateKey.random()[]
|
||||||
|
|
||||||
let payload = Payload(dst: some(privKey.toPublicKey()[]),
|
let payload = Payload(dst: some(privKey.toPublicKey()),
|
||||||
payload: @[byte 0, 1, 2])
|
payload: @[byte 0, 1, 2])
|
||||||
let encoded = whisper.encode(payload)
|
let encoded = whisper.encode(payload)
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ suite "Whisper payload padding":
|
||||||
check:
|
check:
|
||||||
decoded.isSome()
|
decoded.isSome()
|
||||||
payload.payload == decoded.get().payload
|
payload.payload == decoded.get().payload
|
||||||
privKey.toPublicKey()[] == decoded.get().src.get()
|
privKey.toPublicKey() == decoded.get().src.get()
|
||||||
decoded.get().padding.isSome()
|
decoded.get().padding.isSome()
|
||||||
decoded.get().padding.get().len == 256 # as dataLen == 256
|
decoded.get().padding.get().len == 256 # as dataLen == 256
|
||||||
|
|
||||||
|
@ -118,7 +118,7 @@ suite "Whisper payload padding":
|
||||||
check:
|
check:
|
||||||
decoded.isSome()
|
decoded.isSome()
|
||||||
payload.payload == decoded.get().payload
|
payload.payload == decoded.get().payload
|
||||||
privKey.toPublicKey()[] == decoded.get().src.get()
|
privKey.toPublicKey() == decoded.get().src.get()
|
||||||
decoded.get().padding.isSome()
|
decoded.get().padding.isSome()
|
||||||
decoded.get().padding.get().len == 1 # as dataLen == 255
|
decoded.get().padding.get().len == 1 # as dataLen == 255
|
||||||
|
|
||||||
|
@ -156,7 +156,7 @@ suite "Whisper payload padding":
|
||||||
check:
|
check:
|
||||||
decoded.isSome()
|
decoded.isSome()
|
||||||
payload.payload == decoded.get().payload
|
payload.payload == decoded.get().payload
|
||||||
privKey.toPublicKey()[] == decoded.get().src.get()
|
privKey.toPublicKey() == decoded.get().src.get()
|
||||||
decoded.get().padding.isSome()
|
decoded.get().padding.isSome()
|
||||||
payload.padding.get() == decoded.get().padding.get()
|
payload.padding.get() == decoded.get().padding.get()
|
||||||
|
|
||||||
|
@ -171,7 +171,7 @@ suite "Whisper payload padding":
|
||||||
check:
|
check:
|
||||||
decoded.isSome()
|
decoded.isSome()
|
||||||
payload.payload == decoded.get().payload
|
payload.payload == decoded.get().payload
|
||||||
privKey.toPublicKey()[] == decoded.get().src.get()
|
privKey.toPublicKey() == decoded.get().src.get()
|
||||||
decoded.get().padding.isNone()
|
decoded.get().padding.isNone()
|
||||||
|
|
||||||
# example from https://github.com/paritytech/parity-ethereum/blob/93e1040d07e385d1219d00af71c46c720b0a1acf/whisper/src/message.rs#L439
|
# example from https://github.com/paritytech/parity-ethereum/blob/93e1040d07e385d1219d00af71c46c720b0a1acf/whisper/src/message.rs#L439
|
||||||
|
@ -302,7 +302,7 @@ suite "Whisper filter":
|
||||||
test "should notify filter on message with asymmetric encryption":
|
test "should notify filter on message with asymmetric encryption":
|
||||||
let privKey = PrivateKey.random()[]
|
let privKey = PrivateKey.random()[]
|
||||||
let topic = [byte 0, 0, 0, 0]
|
let topic = [byte 0, 0, 0, 0]
|
||||||
let msg = prepFilterTestMsg(pubKey = some(privKey.toPublicKey()[]),
|
let msg = prepFilterTestMsg(pubKey = some(privKey.toPublicKey()),
|
||||||
topic = topic)
|
topic = topic)
|
||||||
|
|
||||||
var filters = initTable[string, Filter]()
|
var filters = initTable[string, Filter]()
|
||||||
|
@ -323,7 +323,7 @@ suite "Whisper filter":
|
||||||
let msg = prepFilterTestMsg(src = some(privKey), topic = topic)
|
let msg = prepFilterTestMsg(src = some(privKey), topic = topic)
|
||||||
|
|
||||||
var filters = initTable[string, Filter]()
|
var filters = initTable[string, Filter]()
|
||||||
let filter = initFilter(src = some(privKey.toPublicKey()[]),
|
let filter = initFilter(src = some(privKey.toPublicKey()),
|
||||||
topics = @[topic])
|
topics = @[topic])
|
||||||
let filterId = filters.subscribeFilter(filter)
|
let filterId = filters.subscribeFilter(filter)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue