2022-09-07 15:15:43 -04:00
|
|
|
package rln
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"encoding/binary"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Each node of the Merkle tee is a Poseidon hash which is a 32 byte value
|
|
|
|
type MerkleNode = [32]byte
|
|
|
|
|
|
|
|
type Nullifier = [32]byte
|
|
|
|
|
|
|
|
type RLNIdentifier = [32]byte
|
|
|
|
|
|
|
|
type ZKSNARK = [128]byte
|
|
|
|
|
2023-03-30 18:13:52 -04:00
|
|
|
type IDTrapdoor = [32]byte
|
|
|
|
|
|
|
|
type IDNullifier = [32]byte
|
|
|
|
|
|
|
|
// identity key as defined in https://hackmd.io/tMTLMYmTR5eynw2lwK9n1w?view#Membership
|
|
|
|
type IDSecretHash = [32]byte
|
|
|
|
|
|
|
|
// IDCommitment is hash of identity key as defined in https://hackmd.io/tMTLMYmTR5eynw2lwK9n1w?view#Membership
|
|
|
|
type IDCommitment = [32]byte
|
2022-09-07 15:15:43 -04:00
|
|
|
|
2023-03-30 18:13:52 -04:00
|
|
|
type IdentityCredential = struct {
|
|
|
|
IDTrapdoor IDTrapdoor `json:"idTrapdoor"`
|
|
|
|
IDNullifier IDNullifier `json:"idNullifier"`
|
2022-09-07 15:15:43 -04:00
|
|
|
// user's identity key (a secret key) which is selected randomly
|
|
|
|
// see details in https://hackmd.io/tMTLMYmTR5eynw2lwK9n1w?view#Membership
|
2023-03-30 18:13:52 -04:00
|
|
|
IDSecretHash IDSecretHash `json:"idSecretHash"`
|
2022-09-07 15:15:43 -04:00
|
|
|
// hash of user's identity key generated by
|
|
|
|
// Poseidon hash function implemented in rln lib
|
|
|
|
// more details in https://hackmd.io/tMTLMYmTR5eynw2lwK9n1w?view#Membership
|
2022-10-09 15:42:15 -04:00
|
|
|
IDCommitment IDCommitment `json:"idCommitment"`
|
2022-09-07 15:15:43 -04:00
|
|
|
}
|
|
|
|
|
2023-04-10 11:06:09 -04:00
|
|
|
func IdentityCredentialEquals(i IdentityCredential, i2 IdentityCredential) bool {
|
|
|
|
return bytes.Equal(i.IDTrapdoor[:], i2.IDTrapdoor[:]) && bytes.Equal(i.IDNullifier[:], i2.IDNullifier[:]) && bytes.Equal(i.IDSecretHash[:], i2.IDSecretHash[:]) && bytes.Equal(i.IDCommitment[:], i2.IDCommitment[:])
|
|
|
|
}
|
|
|
|
|
2022-09-07 15:15:43 -04:00
|
|
|
type RateLimitProof struct {
|
|
|
|
// 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
|
2022-10-09 15:42:15 -04:00
|
|
|
Proof ZKSNARK `json:"proof"`
|
2022-09-07 15:15:43 -04:00
|
|
|
// the root of Merkle tree used for the generation of the `proof`
|
2022-10-09 15:42:15 -04:00
|
|
|
MerkleRoot MerkleNode `json:"root"`
|
2022-09-07 15:15:43 -04:00
|
|
|
// the epoch used for the generation of the `proof`
|
2022-10-09 15:42:15 -04:00
|
|
|
Epoch Epoch `json:"epoch"`
|
2022-09-07 15:15:43 -04:00
|
|
|
// 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
|
2022-10-09 15:42:15 -04:00
|
|
|
ShareX MerkleNode `json:"share_x"`
|
|
|
|
ShareY MerkleNode `json:"share_y"`
|
2022-09-07 15:15:43 -04:00
|
|
|
// nullifier enables linking two messages published during the same epoch
|
|
|
|
// see details in https://hackmd.io/tMTLMYmTR5eynw2lwK9n1w?view#Nullifiers
|
2022-10-09 15:42:15 -04:00
|
|
|
Nullifier Nullifier `json:"nullifier"`
|
2022-09-07 15:15:43 -04:00
|
|
|
// Application specific RLN Identifier
|
2022-10-09 15:42:15 -04:00
|
|
|
RLNIdentifier RLNIdentifier `json:"rlnIdentifier"`
|
2022-09-07 15:15:43 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
type MembershipIndex = uint
|
|
|
|
|
|
|
|
type ProofMetadata struct {
|
2023-03-30 18:13:52 -04:00
|
|
|
Nullifier Nullifier
|
|
|
|
ShareX MerkleNode
|
|
|
|
ShareY MerkleNode
|
|
|
|
ExternalNullifier Nullifier
|
2022-09-07 15:15:43 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
func (p ProofMetadata) Equals(p2 ProofMetadata) bool {
|
2023-03-30 18:13:52 -04:00
|
|
|
return bytes.Equal(p.Nullifier[:], p2.Nullifier[:]) && bytes.Equal(p.ShareX[:], p2.ShareX[:]) && bytes.Equal(p.ShareY[:], p2.ShareY[:]) && bytes.Equal(p.ExternalNullifier[:], p2.ExternalNullifier[:])
|
2022-09-07 15:15:43 -04:00
|
|
|
}
|
|
|
|
|
2022-10-09 15:42:15 -04:00
|
|
|
// the current implementation of the rln lib only supports a circuit for Merkle tree with depth 32
|
2022-09-07 15:15:43 -04:00
|
|
|
const MERKLE_TREE_DEPTH int = 20
|
|
|
|
|
|
|
|
// HASH_BIT_SIZE is the size of poseidon hash output in bits
|
|
|
|
const HASH_BIT_SIZE = 256
|
|
|
|
|
|
|
|
// HASH_HEX_SIZE is the size of poseidon hash output as the number of bytes
|
|
|
|
const HASH_HEX_SIZE = int(HASH_BIT_SIZE / 8)
|
|
|
|
|
|
|
|
// temporary variables to test waku-rln-relay performance in the static group mode
|
|
|
|
|
|
|
|
const STATIC_GROUP_SIZE = 100
|
|
|
|
|
|
|
|
// STATIC_GROUP_KEYS is a static list of 100 membership keys in the form of (identity key, identity commitment)
|
2022-10-09 15:42:15 -04:00
|
|
|
//
|
|
|
|
// keys are created locally, using createMembershipList proc from waku_rln_relay_utils module, and the results are hardcoded in here
|
|
|
|
// this list is temporary and is created to test the performance of waku-rln-relay for the static groups
|
|
|
|
// in the later versions, this static hardcoded group will be replaced with a dynamic one
|
2022-09-07 15:15:43 -04:00
|
|
|
var STATIC_GROUP_KEYS [][]string
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
STATIC_GROUP_KEYS = [][]string{
|
2023-04-03 17:38:39 -04:00
|
|
|
{"2de8ad2cd30e993ff870a31596df4161343d6f05cfe8501884b807eb22dec066", "11ddb7419b09e862027c0ff978d60fd8fece82b31ede62f5e5b931d9986c383d", "022eb3ca06ca2634c5e5a63bde6cc40455cbdda928236f6ca2495f749172ea53", "0d8bae46e9af5072c2042a4c6960fcfcb5ec945479a4683827aaf1ab8a63e07a"}, {"11ab22ee14e4f53ca76120588a33513a5f212dfa6e24175826cdea72482723a3", "263555637d443f73e6ff88ac5fd95cf1c525e52005ff080f2767a8e56fcb86f8", "19a76ef9a5a868bec4b62434e437d90680e36b9d0099302a9adce38a519c7040", "07061c488d0103f01b7334cd175dcdcbaea4bcb18a3847cd9186866536d246d0"}, {"0acc4beab8a4fe06b775ba52b36d7d8d7890fb62da415277de02bb8d7cbfaca2", "06649c699e795cd10588844aaa481481a718788ba7a138b413f7c735a0f76a3b", "00a0400ed331a6a74dbf3e361f7df612c318f1ebedae26f739e80827e36bb5df", "0cb30c063d0363d5547bfd01b62500b61d2f6d434d7728d96cd7b8219175d85c"}, {"04d56ee5bd17cbda45b2fd5b85c2a147c1d91ac675eaee991859abe314e8509c", "091b97505778841b632fbe6cfce2552e091ea1e71ee0266dfd542ad73e4da476", "2bd71275649625675d418d46347de784bf93952d3b29cb9e24a95962c570c3ff", "0a54271b9bfeeebd7467b4306aeef7b36ba71d4eaa6ef4b6ba311872d2cc1d4a"}, {"215833d966a2d3650c3b3d38829d2dca39b4b557c5e35a3783c41436d54415bd", "28c7c326b89a097da2a3254de930f98b05c3e1a1f6909c20afc4ef67d58948fd", "23d336beac7ea57e699537ae0270a3d7dd7476bb59835468be0b46b336513a00", "05f5d750eb243da48f07e3629451068fab8f9d7c551906af0caca00d2c94c50a"}, {"24520de883497eb171445202d7a82b98f6afa3827bb8064dd568e0546d08f49e", "157ec42e00e8d810ea94f834541a3d0bcc6029c4115269354d3baceb084bed9e", "0954402b0b26bdb7a2da1312cf65ef616dba71fa7c1459e421def2337897116a", "2bf5d1b7e98b51ae9cc300669d6e6d2a6c8d2de575519c6d53dda0c0d0bdde30"}, {"295fa4839e238b1410df304a44e2b59234bc9f87c1e8c8bc09075c64ae16e2b9", "2f90313f25959ed8f080c5a54df6991e460cad3d6312e3b18d029ad05f8e28a8", "0f0c817957603df4edbf7cc3a046e68f09ea7870a31192c48f1fc12e45032031", "1839a530aa56b1f50856a85926c1842e678754e9c3dc059e34eee0bc70f88dd4"}, {"1d0c99e03b6aa94e01f29decd6148230471a5b8e60753b659ed2a891c4e89698", "13d29e820f34e02477c7713a246e662705f33c92dc2e69695228d593e115260d", "006fe254e1c8fbe34555e51224ef97f0ea4eb005168cbd8885a5d99ee73da095", "119b0cebca96186bc219066d781258e04e386097f3c03080a494ae8d01e2bb31"}, {"217fd32fb7bd401ef0229aa2dd1c93c591772bc970249e52621f76a6d529fff3", "0113d56afd15a5ec23eff9d434f4547fdbb3c82029a622391585f5000633f583", "1f677a1bab221a4d5d1c281b635133b9376906dceab0fb36510cb0c2b08efca2", "2971c74b6c9f324a30a83b32d211850230250ade39740055576f0dc85fb98cf0"}, {"2d420d4da783d075faf6aceb5405766f49d08a06a57932f9e0fc58ffb41b4198", "272849724f0faf574008a29597fa21d8f86cdaf3973cfea19a50b59119621a3f", "18189e9e10e820cf3c667c8346b9527213ff3a1945f687138316bb0bb5e65ca4", "056ca699b1c87b5e8598665ef129318935dd3e96492b79113d2451fbae9f1cc6"}, {"1fe33b9a7284967bcd69b14f648a7e4667a59a59e030030abc12864dcf64a681", "1fa7f7a31f8d313d919765e6b4a0e681ca3e1e6f95cbb48d893fad389e1d8859", "2692bb4ca076936d3079735d5c9a6add5a1f02a968b00599a1478114a04891d9", "12b4157333b5b07b785db8a30c73b5c474c5f2649ef47a63d78f1b998cbf59e4"}, {"1d053812ffbe4d4da6e21cb3b8728a60bb6cb2420e29998e78c4ce965c35ec8d", "09d840b025919e2c2b381ecc5bf9fc2dd599e83ea1c2825d17299cb34ab9f6b2", "1824d455c9577d65db341e59ebc7b6cf940bf54af49ae800fb0dc5f32014d249", "2012a26ab7b783808fbcf8b2cc58158a2db725d277c9520b65e5d36e5dc6b052"}, {"132a653c9148ae4f992f223df26541e11d39953e273e47a863ba631c318090b5", "20010c72714dc65285a0201f7bb1cf464e030b0fbf2d2be3177667066a9d07da", "1b3dd5b82723da7f939d882125322f91f74279d0cd858c45e09011a51a4de962", "2601a3ed3ff4a7718f0019a3939c08fc3a9a5a8180a68daaa7bf34cc486bc757"}, {"2f656d8a0c07ac9b2de82be9d3cbf4535cdf169cbc2b355155d9e0ed256cc33d", "1f7c9c1aa1dca7354f135849012aa5968b37ae729b2847694f65355895d41984", "00b8302bd41850608f88ef1b0e6949b08e850fd8d1044b3d23b7224aca5ea7d5", "2c1d654b251d138a3a6be82f784e54b05ce5b6501ce2d59b89021d20abca7516"}, {"168c45a2df3f7f5dc9305277cd8b78d023f817ba5ad198a1ea6b1f23aa002478", "0f50c493b68eaf26cfab59c903ef583f03348d9e839806af0522759d64afac60", "2d1e68d056c1928fe7a44b96cb2333888ef3a169be54f4dd5438fc0de23554d7", "10e58fa7abc99dcafc5f4e08181c095c78aaac093e3a5c5e356
|
2022-09-07 15:15:43 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// STATIC_GROUP_MERKLE_ROOT is the root of the Merkle tree constructed from the STATIC_GROUP_KEYS above
|
|
|
|
// only identity commitments are used for the Merkle tree construction
|
|
|
|
// the root is created locally, using createMembershipList proc from waku_rln_relay_utils module, and the result is hardcoded in here
|
2023-07-26 14:01:45 -04:00
|
|
|
const STATIC_GROUP_MERKLE_ROOT = "ca7290e49680fa14eeaeea709e4742a8a074a1bcbfd50a4b3976742ae8a6ca25"
|
2022-09-07 15:15:43 -04:00
|
|
|
|
|
|
|
const EPOCH_UNIT_SECONDS = uint64(10) // the rln-relay epoch length in seconds
|
|
|
|
|
|
|
|
type Epoch [32]byte
|
|
|
|
|
|
|
|
func BytesToEpoch(b []byte) Epoch {
|
|
|
|
var result Epoch
|
|
|
|
copy(result[:], b)
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
|
|
|
func ToEpoch(t uint64) Epoch {
|
|
|
|
var result Epoch
|
|
|
|
binary.LittleEndian.PutUint64(result[:], t)
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
|
|
|
func (e Epoch) Uint64() uint64 {
|
|
|
|
return binary.LittleEndian.Uint64(e[:])
|
|
|
|
}
|
|
|
|
|
|
|
|
// CalcEpoch returns the corresponding rln `Epoch` value for a time.Time
|
|
|
|
func CalcEpoch(t time.Time) Epoch {
|
|
|
|
return ToEpoch(uint64(t.Unix()) / EPOCH_UNIT_SECONDS)
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetCurrentEpoch gets the current rln Epoch time
|
|
|
|
func GetCurrentEpoch() Epoch {
|
|
|
|
return CalcEpoch(time.Now())
|
|
|
|
}
|
|
|
|
|
|
|
|
// Diff returns the difference between the two rln `Epoch`s `e1` and `e2`
|
|
|
|
func Diff(e1, e2 Epoch) int64 {
|
|
|
|
epoch1 := e1.Uint64()
|
|
|
|
epoch2 := e2.Uint64()
|
|
|
|
return int64(epoch1) - int64(epoch2)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (e Epoch) Time() time.Time {
|
|
|
|
return time.Unix(int64(e.Uint64()*EPOCH_UNIT_SECONDS), 0)
|
|
|
|
}
|