mirror of https://github.com/vacp2p/nim-libp2p.git
Add utility procedures for SECIO.
Add 2 more length encodings for protobuf.
This commit is contained in:
parent
c584583678
commit
f2b10776db
|
@ -8,6 +8,7 @@
|
|||
## those terms.
|
||||
|
||||
## This module implements Public Key and Private Key interface for libp2p.
|
||||
import strutils
|
||||
import rsa, ecnist, ed25519/ed25519, secp
|
||||
import ../protobuf/minprotobuf, ../vbuffer
|
||||
import nimcrypto/[rijndael, blowfish, sha, sha2, hash, hmac, utils]
|
||||
|
@ -572,6 +573,63 @@ proc makeSecret*(remoteEPublic: PublicKey, localEPrivate: PrivateKey,
|
|||
if localEPrivate.scheme == remoteEPublic.scheme:
|
||||
result = toSecret(remoteEPublic.eckey, localEPrivate.eckey, data)
|
||||
|
||||
proc getOrder*(remotePubkey, localNonce: openarray[byte],
|
||||
localPubkey, remoteNonce: openarray[byte]): int =
|
||||
## Compare values and calculate `order` parameter.
|
||||
var ctx: sha256
|
||||
ctx.init()
|
||||
ctx.update(remotePubkey)
|
||||
ctx.update(localNonce)
|
||||
var digest1 = ctx.finish()
|
||||
ctx.init()
|
||||
ctx.update(localPubkey)
|
||||
ctx.update(remoteNonce)
|
||||
var digest2 = ctx.finish()
|
||||
var diff = 0
|
||||
for i in 0 ..< len(digest1.data):
|
||||
diff = int(digest1.data[i]) - int(digest2.data[i])
|
||||
result = (result and -not(diff)) or diff
|
||||
|
||||
proc selectBest*(order: int, p1, p2: string): string =
|
||||
## Determines which algorithm to use from list `p1` and `p2`.
|
||||
##
|
||||
## Returns empty string if there no algorithms in common.
|
||||
var f, s: seq[string]
|
||||
if order < 0:
|
||||
f = strutils.split(p2, ",")
|
||||
s = strutils.split(p1, ",")
|
||||
elif order > 0:
|
||||
f = strutils.split(p1, ",")
|
||||
s = strutils.split(p2, ",")
|
||||
else:
|
||||
var p = strutils.split(p1, ",")
|
||||
result = p[0]
|
||||
return
|
||||
|
||||
for felement in f:
|
||||
for selement in s:
|
||||
if felement == selement:
|
||||
result = felement
|
||||
break
|
||||
|
||||
proc createProposal*(nonce, pubkey: openarray[byte],
|
||||
exchanges, ciphers, hashes: string): seq[byte] =
|
||||
var msg = initProtoBuffer({WithUint32BeLength})
|
||||
msg.write(initProtoField(1, nonce))
|
||||
msg.write(initProtoField(2, pubkey))
|
||||
msg.write(initProtoField(3, exchanges))
|
||||
msg.write(initProtoField(4, ciphers))
|
||||
msg.write(initProtoField(5, hashes))
|
||||
msg.finish()
|
||||
shallowCopy(result, msg.buffer)
|
||||
|
||||
proc createExchange*(epubkey, signature: openarray[byte]): seq[byte] =
|
||||
var msg = initProtoBuffer({WithUint32BeLength})
|
||||
msg.write(initProtoField(1, epubkey))
|
||||
msg.write(initProtoField(2, signature))
|
||||
msg.finish()
|
||||
shallowCopy(result, msg.buffer)
|
||||
|
||||
## Serialization/Deserialization helpers
|
||||
|
||||
proc write*(vb: var VBuffer, pubkey: PublicKey) {.inline.} =
|
||||
|
|
|
@ -20,7 +20,7 @@ type
|
|||
|
||||
ProtoFlags* = enum
|
||||
## Protobuf's encoding types
|
||||
WithVarintLength
|
||||
WithVarintLength, WithUint32BeLength, WithUint32LeLength
|
||||
|
||||
ProtoBuffer* = object
|
||||
## Protobuf's message representation object
|
||||
|
@ -128,6 +128,11 @@ proc initProtoBuffer*(options: set[ProtoFlags] = {}): ProtoBuffer =
|
|||
# in [0, 9].
|
||||
result.buffer.setLen(10)
|
||||
result.offset = 10
|
||||
elif {WithUint32LeLength, WithUint32BeLength} * options != {}:
|
||||
# Our buffer will start from position 4, so we can store length of buffer
|
||||
# in [0, 9].
|
||||
result.buffer.setLen(4)
|
||||
result.offset = 4
|
||||
|
||||
proc write*(pb: var ProtoBuffer, field: ProtoField) =
|
||||
## Encode protobuf's field ``field`` and store it to protobuf's buffer ``pb``.
|
||||
|
@ -184,6 +189,20 @@ proc finish*(pb: var ProtoBuffer) =
|
|||
let res = PB.putUVarint(pb.buffer.toOpenArray(pos, 9), usedBytes, size)
|
||||
doAssert(res == VarintStatus.Success)
|
||||
pb.offset = pos
|
||||
elif WithUint32BeLength in pb.options:
|
||||
let size = uint(len(pb.buffer) - 4)
|
||||
pb.buffer[0] = byte(size shr 24)
|
||||
pb.buffer[1] = byte(size shr 16)
|
||||
pb.buffer[2] = byte(size shr 8)
|
||||
pb.buffer[3] = byte(size)
|
||||
pb.offset = 4
|
||||
elif WithUint32LeLength in pb.options:
|
||||
let size = uint(len(pb.buffer) - 4)
|
||||
pb.buffer[0] = byte(size)
|
||||
pb.buffer[1] = byte(size shr 8)
|
||||
pb.buffer[2] = byte(size shr 16)
|
||||
pb.buffer[3] = byte(size shr 24)
|
||||
pb.offset = 4
|
||||
else:
|
||||
pb.offset = 0
|
||||
|
||||
|
|
Loading…
Reference in New Issue