Fix import bugs.
Add PublicKey and Signature types to daemonapi. Add more tests for crypto.nim
This commit is contained in:
parent
6321689c3c
commit
dc2d0538ff
|
@ -8,11 +8,13 @@
|
||||||
## those terms.
|
## those terms.
|
||||||
|
|
||||||
## This module implements Public Key and Private Key interface for libp2p.
|
## This module implements Public Key and Private Key interface for libp2p.
|
||||||
import rsa, ecnist
|
import rsa, ecnist, ed25519/ed25519
|
||||||
import ed25519/ed25519
|
import ../protobuf/minprotobuf, ../vbuffer
|
||||||
import ../protobuf/minprotobuf
|
|
||||||
import nimcrypto/[rijndael, blowfish, sha, sha2, hash, hmac, utils]
|
import nimcrypto/[rijndael, blowfish, sha, sha2, hash, hmac, utils]
|
||||||
|
|
||||||
|
# This is workaround for Nim's `import` bug
|
||||||
|
export rijndael, blowfish, sha, sha2, hash, hmac, utils
|
||||||
|
|
||||||
type
|
type
|
||||||
PKScheme* = enum
|
PKScheme* = enum
|
||||||
RSA = 0,
|
RSA = 0,
|
||||||
|
@ -69,7 +71,11 @@ type
|
||||||
macsize*: int
|
macsize*: int
|
||||||
data*: seq[byte]
|
data*: seq[byte]
|
||||||
|
|
||||||
|
Signature* = object
|
||||||
|
data*: seq[byte]
|
||||||
|
|
||||||
P2pKeyError* = object of Exception
|
P2pKeyError* = object of Exception
|
||||||
|
P2pSigError* = object of Exception
|
||||||
|
|
||||||
const
|
const
|
||||||
SupportedSchemes* = {RSA, Ed25519, ECDSA}
|
SupportedSchemes* = {RSA, Ed25519, ECDSA}
|
||||||
|
@ -192,6 +198,14 @@ proc toBytes*(key: PublicKey, data: var openarray[byte]): int =
|
||||||
if len(data) >= result:
|
if len(data) >= result:
|
||||||
copyMem(addr data[0], addr msg.buffer[0], len(msg.buffer))
|
copyMem(addr data[0], addr msg.buffer[0], len(msg.buffer))
|
||||||
|
|
||||||
|
proc toBytes*(sig: Signature, data: var openarray[byte]): int =
|
||||||
|
## Serialize signature ``sig`` and store it to ``data``.
|
||||||
|
##
|
||||||
|
## Returns number of bytes (octets) needed to store signature ``sig``.
|
||||||
|
result = len(sig.data)
|
||||||
|
if len(data) >= result:
|
||||||
|
copyMem(addr data[0], unsafeAddr sig.data[0], len(sig.data))
|
||||||
|
|
||||||
proc getBytes*(key: PrivateKey): seq[byte] =
|
proc getBytes*(key: PrivateKey): seq[byte] =
|
||||||
## Return private key ``key`` in binary form (using libp2p's protobuf
|
## Return private key ``key`` in binary form (using libp2p's protobuf
|
||||||
## serialization).
|
## serialization).
|
||||||
|
@ -210,6 +224,10 @@ proc getBytes*(key: PublicKey): seq[byte] =
|
||||||
msg.finish()
|
msg.finish()
|
||||||
result = msg.buffer
|
result = msg.buffer
|
||||||
|
|
||||||
|
proc getBytes*(sig: Signature): seq[byte] =
|
||||||
|
## Return signature ``sig`` in binary form.
|
||||||
|
result = sig.data
|
||||||
|
|
||||||
proc init*(key: var PrivateKey, data: openarray[byte]): bool =
|
proc init*(key: var PrivateKey, data: openarray[byte]): bool =
|
||||||
## Initialize private key ``key`` from libp2p's protobuf serialized raw
|
## Initialize private key ``key`` from libp2p's protobuf serialized raw
|
||||||
## binary form.
|
## binary form.
|
||||||
|
@ -264,6 +282,14 @@ proc init*(key: var PublicKey, data: openarray[byte]): bool =
|
||||||
key = nkey
|
key = nkey
|
||||||
result = true
|
result = true
|
||||||
|
|
||||||
|
proc init*(sig: var Signature, data: openarray[byte]): bool =
|
||||||
|
## Initialize signature ``sig`` from raw binary form.
|
||||||
|
##
|
||||||
|
## Returns ``true`` on success.
|
||||||
|
if len(data) > 0:
|
||||||
|
sig.data = @data
|
||||||
|
result = true
|
||||||
|
|
||||||
proc init*(key: var PrivateKey, data: string): bool =
|
proc init*(key: var PrivateKey, data: string): bool =
|
||||||
## Initialize private key ``key`` from libp2p's protobuf serialized
|
## Initialize private key ``key`` from libp2p's protobuf serialized
|
||||||
## hexadecimal string representation.
|
## hexadecimal string representation.
|
||||||
|
@ -278,6 +304,13 @@ proc init*(key: var PublicKey, data: string): bool =
|
||||||
## Returns ``true`` on success.
|
## Returns ``true`` on success.
|
||||||
result = key.init(fromHex(data))
|
result = key.init(fromHex(data))
|
||||||
|
|
||||||
|
proc init*(sig: var Signature, data: string): bool =
|
||||||
|
## Initialize signature ``sig`` from serialized hexadecimal string
|
||||||
|
## representation.
|
||||||
|
##
|
||||||
|
## Returns ``true`` on success.
|
||||||
|
result = sig.init(fromHex(data))
|
||||||
|
|
||||||
proc init*(t: typedesc[PrivateKey], data: openarray[byte]): PrivateKey =
|
proc init*(t: typedesc[PrivateKey], data: openarray[byte]): PrivateKey =
|
||||||
## Create new private key from libp2p's protobuf serialized binary form.
|
## Create new private key from libp2p's protobuf serialized binary form.
|
||||||
if not result.init(data):
|
if not result.init(data):
|
||||||
|
@ -288,6 +321,11 @@ proc init*(t: typedesc[PublicKey], data: openarray[byte]): PublicKey =
|
||||||
if not result.init(data):
|
if not result.init(data):
|
||||||
raise newException(P2pKeyError, "Incorrect binary form")
|
raise newException(P2pKeyError, "Incorrect binary form")
|
||||||
|
|
||||||
|
proc init*(t: typedesc[Signature], data: openarray[byte]): Signature =
|
||||||
|
## Create new public key from libp2p's protobuf serialized binary form.
|
||||||
|
if not result.init(data):
|
||||||
|
raise newException(P2pSigError, "Incorrect binary form")
|
||||||
|
|
||||||
proc init*(t: typedesc[PrivateKey], data: string): PrivateKey =
|
proc init*(t: typedesc[PrivateKey], data: string): PrivateKey =
|
||||||
## Create new private key from libp2p's protobuf serialized hexadecimal string
|
## Create new private key from libp2p's protobuf serialized hexadecimal string
|
||||||
## form.
|
## form.
|
||||||
|
@ -298,6 +336,10 @@ proc init*(t: typedesc[PublicKey], data: string): PublicKey =
|
||||||
## form.
|
## form.
|
||||||
result = t.init(fromHex(data))
|
result = t.init(fromHex(data))
|
||||||
|
|
||||||
|
proc init*(t: typedesc[Signature], data: string): Signature =
|
||||||
|
## Create new signature from serialized hexadecimal string form.
|
||||||
|
result = t.init(fromHex(data))
|
||||||
|
|
||||||
proc `==`*(key1, key2: PublicKey): bool =
|
proc `==`*(key1, key2: PublicKey): bool =
|
||||||
## Return ``true`` if two public keys ``key1`` and ``key2`` of the same
|
## Return ``true`` if two public keys ``key1`` and ``key2`` of the same
|
||||||
## scheme and equal.
|
## scheme and equal.
|
||||||
|
@ -346,34 +388,38 @@ proc `$`*(key: PublicKey): string =
|
||||||
result.add($(key.eckey))
|
result.add($(key.eckey))
|
||||||
result.add(")")
|
result.add(")")
|
||||||
|
|
||||||
proc sign*(key: PrivateKey, data: openarray[byte]): seq[byte] =
|
proc `$`*(sig: Signature): string =
|
||||||
|
## Get string representation of signature ``sig``.
|
||||||
|
result = toHex(sig.data)
|
||||||
|
|
||||||
|
proc sign*(key: PrivateKey, data: openarray[byte]): Signature =
|
||||||
## Sign message ``data`` using private key ``key`` and return generated
|
## Sign message ``data`` using private key ``key`` and return generated
|
||||||
## signature in raw binary form.
|
## signature in raw binary form.
|
||||||
if key.scheme == RSA:
|
if key.scheme == RSA:
|
||||||
var sig = key.rsakey.sign(data)
|
var sig = key.rsakey.sign(data)
|
||||||
result = sig.getBytes()
|
result.data = sig.getBytes()
|
||||||
elif key.scheme == Ed25519:
|
elif key.scheme == Ed25519:
|
||||||
var sig = key.edkey.sign(data)
|
var sig = key.edkey.sign(data)
|
||||||
result = sig.getBytes()
|
result.data = sig.getBytes()
|
||||||
elif key.scheme == ECDSA:
|
elif key.scheme == ECDSA:
|
||||||
var sig = key.eckey.sign(data)
|
var sig = key.eckey.sign(data)
|
||||||
result = sig.getBytes()
|
result.data = sig.getBytes()
|
||||||
|
|
||||||
proc verify*(sig: openarray[byte], message: openarray[byte],
|
proc verify*(sig: Signature, message: openarray[byte],
|
||||||
key: PublicKey): bool =
|
key: PublicKey): bool =
|
||||||
## Verify signature ``sig`` using message ``message`` and public key ``key``.
|
## Verify signature ``sig`` using message ``message`` and public key ``key``.
|
||||||
## Return ``true`` if message signature is valid.
|
## Return ``true`` if message signature is valid.
|
||||||
if key.scheme == RSA:
|
if key.scheme == RSA:
|
||||||
var signature: RsaSignature
|
var signature: RsaSignature
|
||||||
if signature.init(sig) == Asn1Status.Success:
|
if signature.init(sig.data) == Asn1Status.Success:
|
||||||
result = signature.verify(message, key.rsakey)
|
result = signature.verify(message, key.rsakey)
|
||||||
elif key.scheme == Ed25519:
|
elif key.scheme == Ed25519:
|
||||||
var signature: EdSignature
|
var signature: EdSignature
|
||||||
if signature.init(sig):
|
if signature.init(sig.data):
|
||||||
result = signature.verify(message, key.edkey)
|
result = signature.verify(message, key.edkey)
|
||||||
elif key.scheme == ECDSA:
|
elif key.scheme == ECDSA:
|
||||||
var signature: EcSignature
|
var signature: EcSignature
|
||||||
if signature.init(sig) == Asn1Status.Success:
|
if signature.init(sig.data) == Asn1Status.Success:
|
||||||
result = signature.verify(message, key.eckey)
|
result = signature.verify(message, key.eckey)
|
||||||
|
|
||||||
template makeSecret(buffer, hmactype, secret, seed) =
|
template makeSecret(buffer, hmactype, secret, seed) =
|
||||||
|
@ -485,3 +531,62 @@ proc makeSecret*(remoteEPublic: PublicKey, localEPrivate: PrivateKey,
|
||||||
if remoteEPublic.scheme == ECDSA:
|
if remoteEPublic.scheme == ECDSA:
|
||||||
if localEPrivate.scheme == remoteEPublic.scheme:
|
if localEPrivate.scheme == remoteEPublic.scheme:
|
||||||
result = toSecret(remoteEPublic.eckey, localEPrivate.eckey, data)
|
result = toSecret(remoteEPublic.eckey, localEPrivate.eckey, data)
|
||||||
|
|
||||||
|
## Serialization/Deserialization helpers
|
||||||
|
|
||||||
|
proc write*(vb: var VBuffer, pubkey: PublicKey) {.inline.} =
|
||||||
|
## Write PublicKey value ``pubkey`` to buffer ``vb``.
|
||||||
|
vb.writeSeq(pubkey.getBytes())
|
||||||
|
|
||||||
|
proc write*(vb: var VBuffer, seckey: PrivateKey) {.inline.} =
|
||||||
|
## Write PrivateKey value ``seckey`` to buffer ``vb``.
|
||||||
|
vb.writeSeq(seckey.getBytes())
|
||||||
|
|
||||||
|
proc write*(vb: var VBuffer, sig: PrivateKey) {.inline.} =
|
||||||
|
## Write Signature value ``sig`` to buffer ``vb``.
|
||||||
|
vb.writeSeq(sig.getBytes())
|
||||||
|
|
||||||
|
proc initProtoField*(index: int, pubkey: PublicKey): ProtoField =
|
||||||
|
## Initialize ProtoField with PublicKey ``pubkey``.
|
||||||
|
result = initProtoField(index, pubkey.getBytes())
|
||||||
|
|
||||||
|
proc initProtoField*(index: int, seckey: PrivateKey): ProtoField =
|
||||||
|
## Initialize ProtoField with PrivateKey ``seckey``.
|
||||||
|
result = initProtoField(index, seckey.getBytes())
|
||||||
|
|
||||||
|
proc initProtoField*(index: int, sig: Signature): ProtoField =
|
||||||
|
## Initialize ProtoField with Signature ``sig``.
|
||||||
|
result = initProtoField(index, sig.getBytes())
|
||||||
|
|
||||||
|
proc getValue*(data: var ProtoBuffer, field: int, value: var PublicKey): int =
|
||||||
|
## Read ``PublicKey`` from ProtoBuf's message and validate it.
|
||||||
|
var buf: seq[byte]
|
||||||
|
var key: PublicKey
|
||||||
|
result = getLengthValue(data, field, buf)
|
||||||
|
if result > 0:
|
||||||
|
if not key.init(buf):
|
||||||
|
result = -1
|
||||||
|
else:
|
||||||
|
value = key
|
||||||
|
|
||||||
|
proc getValue*(data: var ProtoBuffer, field: int, value: var PrivateKey): int =
|
||||||
|
## Read ``PrivateKey`` from ProtoBuf's message and validate it.
|
||||||
|
var buf: seq[byte]
|
||||||
|
var key: PrivateKey
|
||||||
|
result = getLengthValue(data, field, buf)
|
||||||
|
if result > 0:
|
||||||
|
if not key.init(buf):
|
||||||
|
result = -1
|
||||||
|
else:
|
||||||
|
value = key
|
||||||
|
|
||||||
|
proc getValue*(data: var ProtoBuffer, field: int, value: var Signature): int =
|
||||||
|
## Read ``Signature`` from ProtoBuf's message and validate it.
|
||||||
|
var buf: seq[byte]
|
||||||
|
var sig: Signature
|
||||||
|
result = getLengthValue(data, field, buf)
|
||||||
|
if result > 0:
|
||||||
|
if not sig.init(buf):
|
||||||
|
result = -1
|
||||||
|
else:
|
||||||
|
value = sig
|
||||||
|
|
|
@ -14,7 +14,33 @@ import constants
|
||||||
import nimcrypto/[hash, sha2, sysrand, utils]
|
import nimcrypto/[hash, sha2, sysrand, utils]
|
||||||
|
|
||||||
# This workaround needed because of some bugs in Nim Static[T].
|
# This workaround needed because of some bugs in Nim Static[T].
|
||||||
export sha2
|
export hash, sha2
|
||||||
|
|
||||||
|
const
|
||||||
|
EdPrivateKeySize* = 64
|
||||||
|
## Size in octets (bytes) of serialized ED25519 private key.
|
||||||
|
EdPublicKeySize* = 32
|
||||||
|
## Size in octets (bytes) of serialized ED25519 public key.
|
||||||
|
EdSignatureSize* = 64
|
||||||
|
## Size in octets (bytes) of serialized ED25519 signature.
|
||||||
|
|
||||||
|
type
|
||||||
|
EdPrivateKey* = object
|
||||||
|
data*: array[EdPrivateKeySize, byte]
|
||||||
|
|
||||||
|
EdPublicKey* = object
|
||||||
|
data*: array[EdPublicKeySize, byte]
|
||||||
|
|
||||||
|
EdSignature* = object
|
||||||
|
data*: array[EdSignatureSize, byte]
|
||||||
|
|
||||||
|
EdKeyPair* = object
|
||||||
|
seckey*: EdPrivateKey
|
||||||
|
pubkey*: EdPublicKey
|
||||||
|
|
||||||
|
EdError* = object of Exception
|
||||||
|
EdRngError* = object of EdError
|
||||||
|
EdIncorrectError* = object of EdError
|
||||||
|
|
||||||
proc `-`(x: uint32): uint32 {.inline.} =
|
proc `-`(x: uint32): uint32 {.inline.} =
|
||||||
result = (0xFFFF_FFFF'u32 - x) + 1'u32
|
result = (0xFFFF_FFFF'u32 - x) + 1'u32
|
||||||
|
@ -1612,32 +1638,6 @@ proc checkScalar*(scalar: openarray[byte]): uint32 =
|
||||||
c = -1
|
c = -1
|
||||||
result = NEQ(z, 0'u32) and LT0(c)
|
result = NEQ(z, 0'u32) and LT0(c)
|
||||||
|
|
||||||
const
|
|
||||||
EdPrivateKeySize* = 64
|
|
||||||
## Size in octets (bytes) of serialized ED25519 private key.
|
|
||||||
EdPublicKeySize* = 32
|
|
||||||
## Size in octets (bytes) of serialized ED25519 public key.
|
|
||||||
EdSignatureSize* = 64
|
|
||||||
## Size in octets (bytes) of serialized ED25519 signature.
|
|
||||||
|
|
||||||
type
|
|
||||||
EdPrivateKey* = object
|
|
||||||
data*: array[EdPrivateKeySize, byte]
|
|
||||||
|
|
||||||
EdPublicKey* = object
|
|
||||||
data*: array[EdPublicKeySize, byte]
|
|
||||||
|
|
||||||
EdSignature* = object
|
|
||||||
data*: array[EdSignatureSize, byte]
|
|
||||||
|
|
||||||
EdKeyPair* = object
|
|
||||||
seckey*: EdPrivateKey
|
|
||||||
pubkey*: EdPublicKey
|
|
||||||
|
|
||||||
EdError* = object of Exception
|
|
||||||
EdRngError* = object of EdError
|
|
||||||
EdIncorrectError* = object of EdError
|
|
||||||
|
|
||||||
proc random*(t: typedesc[EdPrivateKey]): EdPrivateKey =
|
proc random*(t: typedesc[EdPrivateKey]): EdPrivateKey =
|
||||||
## Generate new random ED25519 private key using OS specific CSPRNG.
|
## Generate new random ED25519 private key using OS specific CSPRNG.
|
||||||
var
|
var
|
||||||
|
@ -1645,11 +1645,11 @@ proc random*(t: typedesc[EdPrivateKey]): EdPrivateKey =
|
||||||
pk: array[EdPublicKeySize, byte]
|
pk: array[EdPublicKeySize, byte]
|
||||||
if randomBytes(result.data.toOpenArray(0, 31)) != 32:
|
if randomBytes(result.data.toOpenArray(0, 31)) != 32:
|
||||||
raise newException(EdRngError, "Could not generate random data")
|
raise newException(EdRngError, "Could not generate random data")
|
||||||
var hash = sha512.digest(result.data.toOpenArray(0, 31))
|
var hh = sha512.digest(result.data.toOpenArray(0, 31))
|
||||||
hash.data[0] = hash.data[0] and 0xF8'u8
|
hh.data[0] = hh.data[0] and 0xF8'u8
|
||||||
hash.data[31] = hash.data[31] and 0x3F'u8
|
hh.data[31] = hh.data[31] and 0x3F'u8
|
||||||
hash.data[31] = hash.data[31] or 0x40'u8
|
hh.data[31] = hh.data[31] or 0x40'u8
|
||||||
geScalarMultBase(point, hash.data)
|
geScalarMultBase(point, hh.data)
|
||||||
geP3ToBytes(pk, point)
|
geP3ToBytes(pk, point)
|
||||||
copyMem(addr result.data[32], addr pk[0], 32)
|
copyMem(addr result.data[32], addr pk[0], 32)
|
||||||
|
|
||||||
|
@ -1659,11 +1659,11 @@ proc random*(t: typedesc[EdKeyPair]): EdKeyPair =
|
||||||
var point: GeP3
|
var point: GeP3
|
||||||
if randomBytes(result.seckey.data.toOpenArray(0, 31)) != 32:
|
if randomBytes(result.seckey.data.toOpenArray(0, 31)) != 32:
|
||||||
raise newException(EdRngError, "Could not generate random data")
|
raise newException(EdRngError, "Could not generate random data")
|
||||||
var hash = sha512.digest(result.seckey.data.toOpenArray(0, 31))
|
var hh = sha512.digest(result.seckey.data.toOpenArray(0, 31))
|
||||||
hash.data[0] = hash.data[0] and 0xF8'u8
|
hh.data[0] = hh.data[0] and 0xF8'u8
|
||||||
hash.data[31] = hash.data[31] and 0x3F'u8
|
hh.data[31] = hh.data[31] and 0x3F'u8
|
||||||
hash.data[31] = hash.data[31] or 0x40'u8
|
hh.data[31] = hh.data[31] or 0x40'u8
|
||||||
geScalarMultBase(point, hash.data)
|
geScalarMultBase(point, hh.data)
|
||||||
geP3ToBytes(result.pubkey.data, point)
|
geP3ToBytes(result.pubkey.data, point)
|
||||||
copyMem(addr result.seckey.data[32], addr result.pubkey.data[0], 32)
|
copyMem(addr result.seckey.data[32], addr result.pubkey.data[0], 32)
|
||||||
|
|
||||||
|
|
|
@ -12,8 +12,9 @@ import os, osproc, strutils, tables, streams, strtabs
|
||||||
import chronos
|
import chronos
|
||||||
import ../varint, ../multiaddress, ../multicodec, ../base58, ../cid, ../peer
|
import ../varint, ../multiaddress, ../multicodec, ../base58, ../cid, ../peer
|
||||||
import ../wire, ../multihash, ../protobuf/minprotobuf
|
import ../wire, ../multihash, ../protobuf/minprotobuf
|
||||||
|
import ../crypto/crypto
|
||||||
|
|
||||||
export peer, multiaddress, multicodec, multihash, cid
|
export peer, multiaddress, multicodec, multihash, cid, crypto
|
||||||
|
|
||||||
when not defined(windows):
|
when not defined(windows):
|
||||||
import posix
|
import posix
|
||||||
|
@ -78,9 +79,7 @@ type
|
||||||
VALUE = 1,
|
VALUE = 1,
|
||||||
END = 2
|
END = 2
|
||||||
|
|
||||||
# PeerID* = seq[byte]
|
|
||||||
MultiProtocol* = string
|
MultiProtocol* = string
|
||||||
LibP2PPublicKey* = seq[byte]
|
|
||||||
DHTValue* = seq[byte]
|
DHTValue* = seq[byte]
|
||||||
|
|
||||||
P2PStreamFlags* {.pure.} = enum
|
P2PStreamFlags* {.pure.} = enum
|
||||||
|
@ -137,8 +136,8 @@ type
|
||||||
data*: seq[byte]
|
data*: seq[byte]
|
||||||
seqno*: seq[byte]
|
seqno*: seq[byte]
|
||||||
topics*: seq[string]
|
topics*: seq[string]
|
||||||
signature*: seq[byte]
|
signature*: Signature
|
||||||
key*: seq[byte]
|
key*: PublicKey
|
||||||
|
|
||||||
P2PStreamCallback* = proc(api: DaemonAPI,
|
P2PStreamCallback* = proc(api: DaemonAPI,
|
||||||
stream: P2PStream): Future[void] {.gcsafe.}
|
stream: P2PStream): Future[void] {.gcsafe.}
|
||||||
|
@ -662,7 +661,7 @@ proc newDaemonApi*(flags: set[P2PDaemonFlags] = {},
|
||||||
raise newException(DaemonLocalError, "Could not find daemon executable!")
|
raise newException(DaemonLocalError, "Could not find daemon executable!")
|
||||||
|
|
||||||
# Starting daemon process
|
# Starting daemon process
|
||||||
echo "Starting ", cmd, " ", args.join(" ")
|
# echo "Starting ", cmd, " ", args.join(" ")
|
||||||
api.process = startProcess(cmd, "", args, env, {poStdErrToStdOut})
|
api.process = startProcess(cmd, "", args, env, {poStdErrToStdOut})
|
||||||
# Waiting until daemon will not be bound to control socket.
|
# Waiting until daemon will not be bound to control socket.
|
||||||
while true:
|
while true:
|
||||||
|
@ -928,6 +927,10 @@ proc dhtGetSingleValue(pb: var ProtoBuffer): seq[byte] =
|
||||||
if pb.getLengthValue(3, result) == -1:
|
if pb.getLengthValue(3, result) == -1:
|
||||||
raise newException(DaemonLocalError, "Missing field `value`!")
|
raise newException(DaemonLocalError, "Missing field `value`!")
|
||||||
|
|
||||||
|
proc dhtGetSinglePublicKey(pb: var ProtoBuffer): PublicKey =
|
||||||
|
if pb.getValue(3, result) == -1:
|
||||||
|
raise newException(DaemonLocalError, "Missing field `value`!")
|
||||||
|
|
||||||
proc dhtGetSinglePeerID(pb: var ProtoBuffer): PeerID =
|
proc dhtGetSinglePeerID(pb: var ProtoBuffer): PeerID =
|
||||||
if pb.getValue(3, result) == -1:
|
if pb.getValue(3, result) == -1:
|
||||||
raise newException(DaemonLocalError, "Missing field `value`!")
|
raise newException(DaemonLocalError, "Missing field `value`!")
|
||||||
|
@ -975,7 +978,7 @@ proc dhtFindPeer*(api: DaemonAPI, peer: PeerID,
|
||||||
await api.closeConnection(transp)
|
await api.closeConnection(transp)
|
||||||
|
|
||||||
proc dhtGetPublicKey*(api: DaemonAPI, peer: PeerID,
|
proc dhtGetPublicKey*(api: DaemonAPI, peer: PeerID,
|
||||||
timeout = 0): Future[LibP2PPublicKey] {.async.} =
|
timeout = 0): Future[PublicKey] {.async.} =
|
||||||
## Get peer's public key from peer with id ``peer``.
|
## Get peer's public key from peer with id ``peer``.
|
||||||
##
|
##
|
||||||
## You can specify timeout for DHT request with ``timeout`` value. ``0`` value
|
## You can specify timeout for DHT request with ``timeout`` value. ``0`` value
|
||||||
|
@ -985,7 +988,7 @@ proc dhtGetPublicKey*(api: DaemonAPI, peer: PeerID,
|
||||||
var pb = await transp.transactMessage(requestDHTGetPublicKey(peer, timeout))
|
var pb = await transp.transactMessage(requestDHTGetPublicKey(peer, timeout))
|
||||||
withMessage(pb) do:
|
withMessage(pb) do:
|
||||||
pb.enterDhtMessage(DHTResponseType.VALUE)
|
pb.enterDhtMessage(DHTResponseType.VALUE)
|
||||||
result = pb.dhtGetSingleValue()
|
result = pb.dhtGetSinglePublicKey()
|
||||||
finally:
|
finally:
|
||||||
await api.closeConnection(transp)
|
await api.closeConnection(transp)
|
||||||
|
|
||||||
|
@ -1178,8 +1181,6 @@ proc pubsubPublish*(api: DaemonAPI, topic: string,
|
||||||
proc getPubsubMessage*(pb: var ProtoBuffer): PubSubMessage =
|
proc getPubsubMessage*(pb: var ProtoBuffer): PubSubMessage =
|
||||||
result.data = newSeq[byte]()
|
result.data = newSeq[byte]()
|
||||||
result.seqno = newSeq[byte]()
|
result.seqno = newSeq[byte]()
|
||||||
result.signature = newSeq[byte]()
|
|
||||||
result.key = newSeq[byte]()
|
|
||||||
discard pb.getValue(1, result.peer)
|
discard pb.getValue(1, result.peer)
|
||||||
discard pb.getBytes(2, result.data)
|
discard pb.getBytes(2, result.data)
|
||||||
discard pb.getBytes(3, result.seqno)
|
discard pb.getBytes(3, result.seqno)
|
||||||
|
@ -1193,8 +1194,8 @@ proc getPubsubMessage*(pb: var ProtoBuffer): PubSubMessage =
|
||||||
result.topics = newSeq[string]()
|
result.topics = newSeq[string]()
|
||||||
result.topics.add(stritem)
|
result.topics.add(stritem)
|
||||||
item.setLen(0)
|
item.setLen(0)
|
||||||
discard pb.getBytes(5, result.signature)
|
discard pb.getValue(5, result.signature)
|
||||||
discard pb.getBytes(6, result.key)
|
discard pb.getValue(6, result.key)
|
||||||
|
|
||||||
proc pubsubLoop(api: DaemonAPI, ticket: PubsubTicket) {.async.} =
|
proc pubsubLoop(api: DaemonAPI, ticket: PubsubTicket) {.async.} =
|
||||||
while true:
|
while true:
|
||||||
|
|
|
@ -24,6 +24,9 @@ import tables
|
||||||
import nimcrypto/[sha, sha2, keccak, blake2, hash, utils]
|
import nimcrypto/[sha, sha2, keccak, blake2, hash, utils]
|
||||||
import varint, vbuffer, base58, multicodec, multibase
|
import varint, vbuffer, base58, multicodec, multibase
|
||||||
|
|
||||||
|
# This is workaround for Nim `import` bug.
|
||||||
|
export sha, sha2, keccak, blake2, hash, utils
|
||||||
|
|
||||||
const
|
const
|
||||||
MaxHashSize* = 128
|
MaxHashSize* = 128
|
||||||
|
|
||||||
|
|
|
@ -342,9 +342,6 @@ const
|
||||||
"FA5CB0689A1DFDBAE8618BC079D70E318377B0DA"
|
"FA5CB0689A1DFDBAE8618BC079D70E318377B0DA"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
proc cmp(a, b: openarray[byte]): bool =
|
proc cmp(a, b: openarray[byte]): bool =
|
||||||
result = (@a == @b)
|
result = (@a == @b)
|
||||||
|
|
||||||
|
@ -390,6 +387,70 @@ suite "Key interface test suite":
|
||||||
toHex(checkseckey) == stripSpaces(PrivateKeys[i])
|
toHex(checkseckey) == stripSpaces(PrivateKeys[i])
|
||||||
toHex(checkpubkey) == stripSpaces(PublicKeys[i])
|
toHex(checkpubkey) == stripSpaces(PublicKeys[i])
|
||||||
|
|
||||||
|
test "Generate/Sign/Serialize/Deserialize/Verify test":
|
||||||
|
var msg = "message to sign"
|
||||||
|
var bmsg = cast[seq[byte]](msg)
|
||||||
|
|
||||||
|
for i in 0..<5:
|
||||||
|
var seckey = PrivateKey.random(ECDSA)
|
||||||
|
var pubkey = seckey.getKey()
|
||||||
|
var pair = KeyPair.random(ECDSA)
|
||||||
|
var sig1 = pair.seckey.sign(bmsg)
|
||||||
|
var sig2 = seckey.sign(bmsg)
|
||||||
|
var sersig1 = sig1.getBytes()
|
||||||
|
var sersig2 = sig2.getBytes()
|
||||||
|
var serpub1 = pair.pubkey.getBytes()
|
||||||
|
var serpub2 = pubkey.getBytes()
|
||||||
|
var recsig1 = Signature.init(sersig1)
|
||||||
|
var recsig2 = Signature.init(sersig2)
|
||||||
|
var recpub1 = PublicKey.init(serpub1)
|
||||||
|
var recpub2 = PublicKey.init(serpub2)
|
||||||
|
check:
|
||||||
|
sig1.verify(bmsg, pair.pubkey) == true
|
||||||
|
recsig1.verify(bmsg, recpub1) == true
|
||||||
|
sig2.verify(bmsg, pubkey) == true
|
||||||
|
recsig2.verify(bmsg, recpub2) == true
|
||||||
|
|
||||||
|
for i in 0..<5:
|
||||||
|
var seckey = PrivateKey.random(Ed25519)
|
||||||
|
var pubkey = seckey.getKey()
|
||||||
|
var pair = KeyPair.random(Ed25519)
|
||||||
|
var sig1 = pair.seckey.sign(bmsg)
|
||||||
|
var sig2 = seckey.sign(bmsg)
|
||||||
|
var sersig1 = sig1.getBytes()
|
||||||
|
var sersig2 = sig2.getBytes()
|
||||||
|
var serpub1 = pair.pubkey.getBytes()
|
||||||
|
var serpub2 = pubkey.getBytes()
|
||||||
|
var recsig1 = Signature.init(sersig1)
|
||||||
|
var recsig2 = Signature.init(sersig2)
|
||||||
|
var recpub1 = PublicKey.init(serpub1)
|
||||||
|
var recpub2 = PublicKey.init(serpub2)
|
||||||
|
check:
|
||||||
|
sig1.verify(bmsg, pair.pubkey) == true
|
||||||
|
recsig1.verify(bmsg, recpub1) == true
|
||||||
|
sig2.verify(bmsg, pubkey) == true
|
||||||
|
recsig2.verify(bmsg, recpub2) == true
|
||||||
|
|
||||||
|
for i in 0..<5:
|
||||||
|
var seckey = PrivateKey.random(RSA, 512)
|
||||||
|
var pubkey = seckey.getKey()
|
||||||
|
var pair = KeyPair.random(RSA, 512)
|
||||||
|
var sig1 = pair.seckey.sign(bmsg)
|
||||||
|
var sig2 = seckey.sign(bmsg)
|
||||||
|
var sersig1 = sig1.getBytes()
|
||||||
|
var sersig2 = sig2.getBytes()
|
||||||
|
var serpub1 = pair.pubkey.getBytes()
|
||||||
|
var serpub2 = pubkey.getBytes()
|
||||||
|
var recsig1 = Signature.init(sersig1)
|
||||||
|
var recsig2 = Signature.init(sersig2)
|
||||||
|
var recpub1 = PublicKey.init(serpub1)
|
||||||
|
var recpub2 = PublicKey.init(serpub2)
|
||||||
|
check:
|
||||||
|
sig1.verify(bmsg, pair.pubkey) == true
|
||||||
|
recsig1.verify(bmsg, recpub1) == true
|
||||||
|
sig2.verify(bmsg, pubkey) == true
|
||||||
|
recsig2.verify(bmsg, recpub2) == true
|
||||||
|
|
||||||
test "Go key stretch function AES128-SHA256 test vectors":
|
test "Go key stretch function AES128-SHA256 test vectors":
|
||||||
check testStretcher(0, 4, Aes128, Sha256) == true
|
check testStretcher(0, 4, Aes128, Sha256) == true
|
||||||
test "Go key stretch function AES256-SHA512 test vectors":
|
test "Go key stretch function AES256-SHA512 test vectors":
|
||||||
|
|
Loading…
Reference in New Issue