2021-07-22 08:43:41 +00:00
{. push raises : [ Defect ] . }
2022-05-10 21:09:18 +00:00
import
2022-09-27 04:40:04 +00:00
std / [ tables , deques ] ,
2021-07-22 08:43:41 +00:00
options , chronos , stint ,
2021-06-08 18:56:32 +00:00
web3 ,
2021-10-20 00:37:29 +00:00
eth / keys ,
libp2p / protobuf / minprotobuf ,
2022-06-16 14:04:47 +00:00
stew / arrayops ,
2022-09-30 12:43:42 +00:00
waku_rln_relay_constants ,
2022-06-16 14:04:47 +00:00
.. / .. / utils / protobuf
2021-06-08 18:56:32 +00:00
2022-11-04 03:00:42 +00:00
type RlnRelayResult * [ T ] = Result [ T , string ]
2022-08-05 20:58:19 +00:00
when defined ( rln ) or ( not defined ( rln ) and not defined ( rlnzerokit ) ) :
## Bn256 and RLN are Nim wrappers for the data types used in
## the rln library https://github.com/kilic/rln/blob/3bbec368a4adc68cd5f9bfae80b17e1bbb4ef373/src/ffi.rs
type Bn256 * = pointer
type RLN * [ E ] = pointer
2022-11-04 03:00:42 +00:00
type RLNResult * = RlnRelayResult [ RLN [ Bn256 ] ]
2021-08-24 19:25:29 +00:00
2022-08-05 20:58:19 +00:00
when defined ( rlnzerokit ) :
## RLN is a Nim wrapper for the data types used in zerokit RLN
type RLN * {. incompleteStruct . } = object
2022-11-04 03:00:42 +00:00
type RLNResult * = RlnRelayResult [ ptr RLN ]
2021-06-08 18:56:32 +00:00
2022-05-10 21:09:18 +00:00
type
2021-10-20 00:37:29 +00:00
# identity key as defined in https://hackmd.io/tMTLMYmTR5eynw2lwK9n1w?view#Membership
IDKey * = array [ 32 , byte ]
# hash of identity key as defined ed in https://hackmd.io/tMTLMYmTR5eynw2lwK9n1w?view#Membership
IDCommitment * = array [ 32 , byte ]
2022-05-10 21:09:18 +00:00
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 ]
2022-10-04 20:20:44 +00:00
RlnIdentifier * = array [ 32 , byte ]
2021-08-26 23:14:51 +00:00
2022-08-05 20:58:19 +00:00
when defined ( rln ) or ( not defined ( rln ) and not defined ( rlnzerokit ) ) :
type
ZKSNARK * = array [ 256 , byte ]
when defined ( rlnzerokit ) :
type
ZKSNARK * = array [ 128 , byte ]
2022-10-04 20:20:44 +00:00
2022-08-05 20:58:19 +00:00
2021-06-08 18:56:32 +00:00
# Custom data types defined for waku rln relay -------------------------
2022-05-10 21:09:18 +00:00
type MembershipKeyPair * = object
## user's identity key (a secret key) which is selected randomly
2021-10-20 00:37:29 +00:00
## see details in https://hackmd.io/tMTLMYmTR5eynw2lwK9n1w?view#Membership
2022-05-10 21:09:18 +00:00
idKey * : IDKey
# hash of user's identity key generated by
2021-08-26 23:14:51 +00:00
# Poseidon hash function implemented in rln lib
2021-10-20 00:37:29 +00:00
# more details in https://hackmd.io/tMTLMYmTR5eynw2lwK9n1w?view#Membership
2022-05-10 21:09:18 +00:00
idCommitment * : IDCommitment
2021-06-08 18:56:32 +00:00
2022-10-04 20:20:44 +00:00
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
## the epoch used for the generation of the `proof`
epoch * : Epoch
## 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
## Application specific RLN Identifier
rlnIdentifier * : RlnIdentifier
2022-08-05 20:58:19 +00:00
2022-08-05 10:48:01 +00:00
type MembershipIndex * = uint
type RlnMembershipCredentials * = object
membershipKeyPair * : MembershipKeyPair
rlnIndex * : MembershipIndex
2021-11-23 22:48:40 +00:00
type ProofMetadata * = object
nullifier * : Nullifier
shareX * : MerkleNode
shareY * : MerkleNode
2022-08-05 20:58:19 +00:00
when defined ( rln ) or ( not defined ( rln ) and not defined ( rlnzerokit ) ) :
type WakuRLNRelay * = ref object
membershipKeyPair * : MembershipKeyPair
# membershipIndex denotes the index of a leaf in the Merkle tree
# that contains the pk of the current peer
# this index is used to retrieve the peer's authentication path
membershipIndex * : MembershipIndex
membershipContractAddress * : Address
ethClientAddress * : string
2022-10-12 02:18:11 +00:00
ethAccountAddress * : Option [ Address ]
2022-08-05 20:58:19 +00:00
# this field is required for signing transactions
# TODO may need to erase this ethAccountPrivateKey when is not used
# TODO may need to make ethAccountPrivateKey mandatory
ethAccountPrivateKey * : Option [ PrivateKey ]
rlnInstance * : RLN [ Bn256 ]
pubsubTopic * : string # the pubsub topic for which rln relay is mounted
# contentTopic should be of type waku_message.ContentTopic, however, due to recursive module dependency, the underlying type of ContentTopic is used instead
# TODO a long-term solution is to place types with recursive dependency inside one file
contentTopic * : string
# the log of nullifiers and Shamir shares of the past messages grouped per epoch
nullifierLog * : Table [ Epoch , seq [ ProofMetadata ] ]
2022-08-24 22:47:06 +00:00
lastEpoch * : Epoch # the epoch of the last published rln message
2022-09-27 04:40:04 +00:00
validMerkleRoots * : Deque [ MerkleNode ] # An array of valid merkle roots, which are updated in a FIFO fashion
2022-11-01 02:45:34 +00:00
lastSeenMembershipIndex * : MembershipIndex # the last seen membership index
2022-08-05 20:58:19 +00:00
when defined ( rlnzerokit ) :
type WakuRLNRelay * = ref object
membershipKeyPair * : MembershipKeyPair
# membershipIndex denotes the index of a leaf in the Merkle tree
# that contains the pk of the current peer
# this index is used to retrieve the peer's authentication path
membershipIndex * : MembershipIndex
membershipContractAddress * : Address
ethClientAddress * : string
2022-10-12 02:18:11 +00:00
ethAccountAddress * : Option [ Address ]
2022-08-05 20:58:19 +00:00
# this field is required for signing transactions
# TODO may need to erase this ethAccountPrivateKey when is not used
# TODO may need to make ethAccountPrivateKey mandatory
ethAccountPrivateKey * : Option [ PrivateKey ]
rlnInstance * : ptr RLN
pubsubTopic * : string # the pubsub topic for which rln relay is mounted
# contentTopic should be of type waku_message.ContentTopic, however, due to recursive module dependency, the underlying type of ContentTopic is used instead
# TODO a long-term solution is to place types with recursive dependency inside one file
contentTopic * : string
# the log of nullifiers and Shamir shares of the past messages grouped per epoch
nullifierLog * : Table [ Epoch , seq [ ProofMetadata ] ]
2022-10-03 09:48:01 +00:00
lastEpoch * : Epoch # the epoch of the last published rln message
2022-09-27 04:40:04 +00:00
validMerkleRoots * : Deque [ MerkleNode ] # An array of valid merkle roots, which are updated in a FIFO fashion
2022-11-01 02:45:34 +00:00
lastSeenMembershipIndex * : MembershipIndex # the last seen membership index
2022-09-27 04:40:04 +00:00
2021-11-23 22:48:40 +00:00
type MessageValidationResult * {. pure . } = enum
2022-05-10 21:09:18 +00:00
Valid , Invalid , Spam
2021-06-08 18:56:32 +00:00
2021-11-23 22:48:40 +00:00
# Protobufs enc and init
2021-10-20 00:37:29 +00:00
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 )
2022-10-04 20:20:44 +00:00
var rlnIdentifier : seq [ byte ]
discard ? pb . getField ( 7 , rlnIdentifier )
discard nsp . rlnIdentifier . copyFrom ( rlnIdentifier )
2022-08-05 20:58:19 +00:00
2022-05-10 21:09:18 +00:00
return ok ( nsp )
2021-10-20 00:37:29 +00:00
2022-05-10 21:09:18 +00:00
proc encode * ( nsp : RateLimitProof ) : ProtoBuffer =
2021-10-20 00:37:29 +00:00
var output = initProtoBuffer ( )
2022-06-16 14:04:47 +00:00
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 )
2022-10-04 20:20:44 +00:00
output . write3 ( 7 , nsp . rlnIdentifier )
2022-08-05 20:58:19 +00:00
2022-06-16 14:04:47 +00:00
output . finish3 ( )
2021-10-20 00:37:29 +00:00
2022-10-04 20:20:44 +00:00
return output