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.
|
## 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 strutils
|
||||||
import rsa, ecnist, ed25519/ed25519, secp
|
import rsa, ecnist, ed25519/ed25519, secp
|
||||||
import ../protobuf/minprotobuf, ../vbuffer
|
import ../protobuf/minprotobuf, ../vbuffer
|
||||||
import nimcrypto/[rijndael, blowfish, sha, sha2, hash, hmac, utils]
|
import nimcrypto/[rijndael, blowfish, sha, sha2, hash, hmac, utils]
|
||||||
|
@ -572,6 +573,63 @@ proc makeSecret*(remoteEPublic: PublicKey, localEPrivate: PrivateKey,
|
||||||
if localEPrivate.scheme == remoteEPublic.scheme:
|
if localEPrivate.scheme == remoteEPublic.scheme:
|
||||||
result = toSecret(remoteEPublic.eckey, localEPrivate.eckey, data)
|
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
|
## Serialization/Deserialization helpers
|
||||||
|
|
||||||
proc write*(vb: var VBuffer, pubkey: PublicKey) {.inline.} =
|
proc write*(vb: var VBuffer, pubkey: PublicKey) {.inline.} =
|
||||||
|
|
|
@ -20,7 +20,7 @@ type
|
||||||
|
|
||||||
ProtoFlags* = enum
|
ProtoFlags* = enum
|
||||||
## Protobuf's encoding types
|
## Protobuf's encoding types
|
||||||
WithVarintLength
|
WithVarintLength, WithUint32BeLength, WithUint32LeLength
|
||||||
|
|
||||||
ProtoBuffer* = object
|
ProtoBuffer* = object
|
||||||
## Protobuf's message representation object
|
## Protobuf's message representation object
|
||||||
|
@ -128,6 +128,11 @@ proc initProtoBuffer*(options: set[ProtoFlags] = {}): ProtoBuffer =
|
||||||
# in [0, 9].
|
# in [0, 9].
|
||||||
result.buffer.setLen(10)
|
result.buffer.setLen(10)
|
||||||
result.offset = 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) =
|
proc write*(pb: var ProtoBuffer, field: ProtoField) =
|
||||||
## Encode protobuf's field ``field`` and store it to protobuf's buffer ``pb``.
|
## 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)
|
let res = PB.putUVarint(pb.buffer.toOpenArray(pos, 9), usedBytes, size)
|
||||||
doAssert(res == VarintStatus.Success)
|
doAssert(res == VarintStatus.Success)
|
||||||
pb.offset = pos
|
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:
|
else:
|
||||||
pb.offset = 0
|
pb.offset = 0
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue