79 lines
2.2 KiB
Nim
79 lines
2.2 KiB
Nim
## Nim-LibP2P
|
|
## Copyright (c) 2019 Status Research & Development GmbH
|
|
## Licensed under either of
|
|
## * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
|
|
## * MIT license ([LICENSE-MIT](LICENSE-MIT))
|
|
## at your option.
|
|
## This file may not be copied, modified, or distributed except according to
|
|
## those terms.
|
|
|
|
import options
|
|
import chronicles, stew/byteutils
|
|
import nimcrypto/sysrand
|
|
import messages, protobuf,
|
|
../../../peer,
|
|
../../../peerinfo,
|
|
../../../crypto/crypto,
|
|
../../../protobuf/minprotobuf
|
|
|
|
logScope:
|
|
topic = "PubSubMessage"
|
|
|
|
const PubSubPrefix = "libp2p-pubsub:"
|
|
|
|
proc msgIdProvider(m: Message): string =
|
|
## default msg id provider
|
|
crypto.toHex(m.seqno) & PeerID.init(m.fromPeer).pretty
|
|
|
|
template msgId*(m: Message): string =
|
|
## calls the ``msgIdProvider`` from
|
|
## the instantiation scope
|
|
##
|
|
mixin msgIdProvider
|
|
m.msgIdProvider()
|
|
|
|
proc fromPeerId*(m: Message): PeerId =
|
|
PeerID.init(m.fromPeer)
|
|
|
|
proc sign*(msg: Message, p: PeerInfo): Message {.gcsafe.} =
|
|
var buff = initProtoBuffer()
|
|
encodeMessage(msg, buff)
|
|
if buff.buffer.len > 0:
|
|
result = msg
|
|
result.signature = p.privateKey.
|
|
sign(PubSubPrefix.toBytes() & buff.buffer).tryGet().
|
|
getBytes()
|
|
|
|
proc verify*(m: Message, p: PeerInfo): bool =
|
|
if m.signature.len > 0 and m.key.len > 0:
|
|
var msg = m
|
|
msg.signature = @[]
|
|
msg.key = @[]
|
|
|
|
var buff = initProtoBuffer()
|
|
encodeMessage(msg, buff)
|
|
|
|
var remote: Signature
|
|
var key: PublicKey
|
|
if remote.init(m.signature) and key.init(m.key):
|
|
trace "verifying signature", remoteSignature = remote
|
|
result = remote.verify(PubSubPrefix.toBytes() & buff.buffer, key)
|
|
|
|
proc newMessage*(p: PeerInfo,
|
|
data: seq[byte],
|
|
topic: string,
|
|
sign: bool = true): Message {.gcsafe.} =
|
|
var seqno: seq[byte] = newSeq[byte](8)
|
|
if randomBytes(addr seqno[0], 8) > 0:
|
|
if p.publicKey.isSome:
|
|
var key: seq[byte] = p.publicKey.get().getBytes().tryGet()
|
|
|
|
result = Message(fromPeer: p.peerId.getBytes(),
|
|
data: data,
|
|
seqno: seqno,
|
|
topicIDs: @[topic])
|
|
if sign:
|
|
result = result.sign(p)
|
|
|
|
result.key = key
|