nwaku/waku/waku_rln_relay/protocol_types.nim

128 lines
3.7 KiB
Nim

when (NimMajor, NimMinor) < (1, 4):
{.push raises: [Defect].}
else:
{.push raises: [].}
import std/[options, tables, deques], stew/arrayops, chronos, web3, eth/keys
import ../waku_core, ../waku_keystore, ../common/protobuf
export waku_keystore, waku_core
type RlnRelayResult*[T] = Result[T, string]
## RLN is a Nim wrapper for the data types used in zerokit RLN
type RLN* {.incompleteStruct.} = object
type RLNResult* = RlnRelayResult[ptr RLN]
type
MerkleNode* = array[32, byte]
# Each node of the Merkle tee is a Poseidon hash which is a 32 byte value
Nullifier* = array[32, byte]
Epoch* = array[32, byte]
RlnIdentifier* = array[32, byte]
ZKSNARK* = array[128, byte]
when defined(rln_v2):
type
MessageId* = uint64
ExternalNullifier* = array[32, byte]
type RateCommitment* = object
idCommitment*: IDCommitment
userMessageLimit*: UserMessageLimit
# Custom data types defined for waku rln relay -------------------------
type RateLimitProof* = object
## RateLimitProof holds the public inputs to rln circuit as
## defined in https://hackmd.io/tMTLMYmTR5eynw2lwK9n1w?view#Public-Inputs
## the `proof` field carries the actual zkSNARK proof
proof*: ZKSNARK
## the root of Merkle tree used for the generation of the `proof`
merkleRoot*: MerkleNode
## shareX and shareY are shares of user's identity key
## these shares are created using Shamir secret sharing scheme
## see details in https://hackmd.io/tMTLMYmTR5eynw2lwK9n1w?view#Linear-Equation-amp-SSS
shareX*: MerkleNode
shareY*: MerkleNode
## nullifier enables linking two messages published during the same epoch
## see details in https://hackmd.io/tMTLMYmTR5eynw2lwK9n1w?view#Nullifiers
nullifier*: Nullifier
## the epoch used for the generation of the `proof`
epoch*: Epoch
## Application specific RLN Identifier
rlnIdentifier*: RlnIdentifier
when defined(rln_v2):
## the external nullifier used for the generation of the `proof` (derived from poseidon([epoch, rln_identifier]))
externalNullifier*: ExternalNullifier
type ProofMetadata* = object
nullifier*: Nullifier
shareX*: MerkleNode
shareY*: MerkleNode
externalNullifier*: Nullifier
type
MessageValidationResult* {.pure.} = enum
Valid
Invalid
Spam
MerkleNodeResult* = RlnRelayResult[MerkleNode]
RateLimitProofResult* = RlnRelayResult[RateLimitProof]
# Protobufs enc and init
proc init*(T: type RateLimitProof, buffer: seq[byte]): ProtoResult[T] =
var nsp: RateLimitProof
let pb = initProtoBuffer(buffer)
var proof: seq[byte]
discard ?pb.getField(1, proof)
discard nsp.proof.copyFrom(proof)
var merkleRoot: seq[byte]
discard ?pb.getField(2, merkleRoot)
discard nsp.merkleRoot.copyFrom(merkleRoot)
var epoch: seq[byte]
discard ?pb.getField(3, epoch)
discard nsp.epoch.copyFrom(epoch)
var shareX: seq[byte]
discard ?pb.getField(4, shareX)
discard nsp.shareX.copyFrom(shareX)
var shareY: seq[byte]
discard ?pb.getField(5, shareY)
discard nsp.shareY.copyFrom(shareY)
var nullifier: seq[byte]
discard ?pb.getField(6, nullifier)
discard nsp.nullifier.copyFrom(nullifier)
var rlnIdentifier: seq[byte]
discard ?pb.getField(7, rlnIdentifier)
discard nsp.rlnIdentifier.copyFrom(rlnIdentifier)
return ok(nsp)
proc encode*(nsp: RateLimitProof): ProtoBuffer =
var output = initProtoBuffer()
output.write3(1, nsp.proof)
output.write3(2, nsp.merkleRoot)
output.write3(3, nsp.epoch)
output.write3(4, nsp.shareX)
output.write3(5, nsp.shareY)
output.write3(6, nsp.nullifier)
output.write3(7, nsp.rlnIdentifier)
output.finish3()
return output
type
SpamHandler* =
proc(wakuMessage: WakuMessage): void {.gcsafe, closure, raises: [Defect].}
RegistrationHandler* =
proc(txHash: string): void {.gcsafe, closure, raises: [Defect].}