mirror of
https://github.com/waku-org/nwaku.git
synced 2025-02-26 14:00:57 +00:00
chore(rln-relay): address laundry list of improvements (#1585)
This commit is contained in:
parent
4066b7490c
commit
92546bd997
@ -332,7 +332,7 @@ suite "Waku rln relay":
|
||||
# prepare the input
|
||||
let
|
||||
msg = "Hello".toBytes()
|
||||
hashInput = appendLength(msg)
|
||||
hashInput = encodeLengthPrefix(msg)
|
||||
hashInputBuffer = toBuffer(hashInput)
|
||||
|
||||
# prepare other inputs to the hash function
|
||||
|
@ -4,7 +4,12 @@ else:
|
||||
{.push raises: [].}
|
||||
|
||||
import
|
||||
stew/results
|
||||
std/sequtils,
|
||||
stew/[results, endians2],
|
||||
stint
|
||||
|
||||
# NOTE: 256-bytes long credentials are due to the use of BN254 in RLN. Other implementations/curves might have a different byte size
|
||||
const CredentialByteSize* = 256
|
||||
|
||||
type
|
||||
IdentityTrapdoor* = seq[byte] #array[32, byte]
|
||||
@ -25,8 +30,60 @@ type IdentityCredential* = object
|
||||
# more details in https://hackmd.io/tMTLMYmTR5eynw2lwK9n1w?view#Membership
|
||||
idCommitment*: IDCommitment
|
||||
|
||||
proc toUInt256*(idCommitment: IDCommitment): UInt256 =
|
||||
let pk = UInt256.fromBytesLE(idCommitment)
|
||||
return pk
|
||||
|
||||
proc toIDCommitment*(idCommitmentUint: UInt256): IDCommitment =
|
||||
let pk = IDCommitment(@(idCommitmentUint.toBytesLE()))
|
||||
return pk
|
||||
|
||||
type MembershipIndex* = uint
|
||||
|
||||
proc toMembershipIndex*(v: UInt256): MembershipIndex =
|
||||
let membershipIndex: MembershipIndex = cast[MembershipIndex](v)
|
||||
return membershipIndex
|
||||
|
||||
# Converts a sequence of tuples containing 4 string (i.e. identity trapdoor, nullifier, secret hash and commitment) to an IndentityCredential
|
||||
type RawMembershipCredentials* = (string, string, string, string)
|
||||
proc toIdentityCredentials*(groupKeys: seq[RawMembershipCredentials]): Result[seq[
|
||||
IdentityCredential], string] =
|
||||
## groupKeys is sequence of membership key tuples in the form of (identity key, identity commitment) all in the hexadecimal format
|
||||
## the toIdentityCredentials proc populates a sequence of IdentityCredentials using the supplied groupKeys
|
||||
## Returns an error if the conversion fails
|
||||
|
||||
var groupIdCredentials = newSeq[IdentityCredential]()
|
||||
|
||||
for i in 0..groupKeys.len-1:
|
||||
try:
|
||||
let
|
||||
idTrapdoor = IdentityTrapdoor(@(hexToUint[CredentialByteSize](groupKeys[i][0]).toBytesLE()))
|
||||
idNullifier = IdentityNullifier(@(hexToUint[CredentialByteSize](groupKeys[i][1]).toBytesLE()))
|
||||
idSecretHash = IdentitySecretHash(@(hexToUint[CredentialByteSize](groupKeys[i][2]).toBytesLE()))
|
||||
idCommitment = IDCommitment(@(hexToUint[CredentialByteSize](groupKeys[i][3]).toBytesLE()))
|
||||
groupIdCredentials.add(IdentityCredential(idTrapdoor: idTrapdoor,
|
||||
idNullifier: idNullifier,
|
||||
idSecretHash: idSecretHash,
|
||||
idCommitment: idCommitment))
|
||||
except ValueError as err:
|
||||
return err("could not convert the group key to bytes: " & err.msg)
|
||||
return ok(groupIdCredentials)
|
||||
|
||||
proc serialize*(idComms: seq[IDCommitment]): seq[byte] =
|
||||
## serializes a seq of IDCommitments to a byte seq
|
||||
## the serialization is based on https://github.com/status-im/nwaku/blob/37bd29fbc37ce5cf636734e7dd410b1ed27b88c8/waku/v2/protocol/waku_rln_relay/rln.nim#L142
|
||||
## the order of serialization is |id_commitment_len<8>|id_commitment<var>|
|
||||
var idCommsBytes = newSeq[byte]()
|
||||
|
||||
# serialize the idComms, with its length prefixed
|
||||
let len = toBytes(uint64(idComms.len), Endianness.littleEndian)
|
||||
idCommsBytes.add(len)
|
||||
|
||||
for idComm in idComms:
|
||||
idCommsBytes = concat(idCommsBytes, @idComm)
|
||||
|
||||
return idCommsBytes
|
||||
|
||||
type MembershipContract* = object
|
||||
chainId*: string
|
||||
address*: string
|
||||
|
@ -55,5 +55,3 @@ const MaxEpochGap* = uint64(MaxClockGapSeconds/EpochUnitSeconds)
|
||||
# RLN Keystore defaults
|
||||
const
|
||||
RLNAppInfo* = AppInfo(application: "nwaku-rln-relay", appIdentifier: "01234567890abcdef", version: "0.1")
|
||||
# NOTE: 256-bytes long credentials are due to the use of BN254 in RLN. Other implementations/curves might have a different byte size
|
||||
CredentialByteSize* = 256
|
@ -24,18 +24,6 @@ export
|
||||
logScope:
|
||||
topics = "waku rln_relay conversion_utils"
|
||||
|
||||
proc toUInt256*(idCommitment: IDCommitment): UInt256 =
|
||||
let pk = UInt256.fromBytesLE(idCommitment)
|
||||
return pk
|
||||
|
||||
proc toIDCommitment*(idCommitmentUint: UInt256): IDCommitment =
|
||||
let pk = IDCommitment(@(idCommitmentUint.toBytesLE()))
|
||||
return pk
|
||||
|
||||
proc toMembershipIndex*(v: UInt256): MembershipIndex =
|
||||
let membershipIndex: MembershipIndex = cast[MembershipIndex](v)
|
||||
return membershipIndex
|
||||
|
||||
proc inHex*(value: IdentityTrapdoor or
|
||||
IdentityNullifier or
|
||||
IdentitySecretHash or
|
||||
@ -52,7 +40,7 @@ proc inHex*(value: IdentityTrapdoor or
|
||||
valueHex = "0" & valueHex
|
||||
return toLowerAscii(valueHex)
|
||||
|
||||
proc appendLength*(input: openArray[byte]): seq[byte] =
|
||||
proc encodeLengthPrefix*(input: openArray[byte]): seq[byte] =
|
||||
## returns length prefixed version of the input
|
||||
## with the following format [len<8>|input<var>]
|
||||
## len: 8-byte value that represents the number of bytes in the `input`
|
||||
@ -64,14 +52,16 @@ proc appendLength*(input: openArray[byte]): seq[byte] =
|
||||
output = concat(@len, @input)
|
||||
return output
|
||||
|
||||
proc serialize*(idSecretHash: IdentitySecretHash, memIndex: MembershipIndex, epoch: Epoch,
|
||||
proc serialize*(idSecretHash: IdentitySecretHash,
|
||||
memIndex: MembershipIndex,
|
||||
epoch: Epoch,
|
||||
msg: openArray[byte]): seq[byte] =
|
||||
## a private proc to convert RateLimitProof and the data to a byte seq
|
||||
## this conversion is used in the proofGen proc
|
||||
## the serialization is done as instructed in https://github.com/kilic/rln/blob/7ac74183f8b69b399e3bc96c1ae8ab61c026dc43/src/public.rs#L146
|
||||
## [ id_key<32> | id_index<8> | epoch<32> | signal_len<8> | signal<var> ]
|
||||
let memIndexBytes = toBytes(uint64(memIndex), Endianness.littleEndian)
|
||||
let lenPrefMsg = appendLength(msg)
|
||||
let lenPrefMsg = encodeLengthPrefix(msg)
|
||||
let output = concat(@idSecretHash, @memIndexBytes, @epoch, lenPrefMsg)
|
||||
return output
|
||||
|
||||
@ -80,7 +70,7 @@ proc serialize*(proof: RateLimitProof, data: openArray[byte]): seq[byte] =
|
||||
## a private proc to convert RateLimitProof and data to a byte seq
|
||||
## this conversion is used in the proof verification proc
|
||||
## [ proof<128> | root<32> | epoch<32> | share_x<32> | share_y<32> | nullifier<32> | rln_identifier<32> | signal_len<8> | signal<var> ]
|
||||
let lenPrefMsg = appendLength(@data)
|
||||
let lenPrefMsg = encodeLengthPrefix(@data)
|
||||
var proofBytes = concat(@(proof.proof),
|
||||
@(proof.merkleRoot),
|
||||
@(proof.epoch),
|
||||
@ -99,45 +89,6 @@ proc serialize*(roots: seq[MerkleNode]): seq[byte] =
|
||||
rootsBytes = concat(rootsBytes, @root)
|
||||
return rootsBytes
|
||||
|
||||
proc serializeIdCommitments*(idComms: seq[IDCommitment]): seq[byte] =
|
||||
## serializes a seq of IDCommitments to a byte seq
|
||||
## the serialization is based on https://github.com/status-im/nwaku/blob/37bd29fbc37ce5cf636734e7dd410b1ed27b88c8/waku/v2/protocol/waku_rln_relay/rln.nim#L142
|
||||
## the order of serialization is |id_commitment_len<8>|id_commitment<var>|
|
||||
var idCommsBytes = newSeq[byte]()
|
||||
|
||||
# serialize the idComms, with its length prefixed
|
||||
let len = toBytes(uint64(idComms.len), Endianness.littleEndian)
|
||||
idCommsBytes.add(len)
|
||||
|
||||
for idComm in idComms:
|
||||
idCommsBytes = concat(idCommsBytes, @idComm)
|
||||
|
||||
return idCommsBytes
|
||||
|
||||
# Converts a sequence of tuples containing 4 string (i.e. identity trapdoor, nullifier, secret hash and commitment) to an IndentityCredential
|
||||
type RawMembershipCredentials* = (string, string, string, string)
|
||||
proc toIdentityCredentials*(groupKeys: seq[RawMembershipCredentials]): RlnRelayResult[seq[
|
||||
IdentityCredential]] =
|
||||
## groupKeys is sequence of membership key tuples in the form of (identity key, identity commitment) all in the hexadecimal format
|
||||
## the toIdentityCredentials proc populates a sequence of IdentityCredentials using the supplied groupKeys
|
||||
## Returns an error if the conversion fails
|
||||
|
||||
var groupIdCredentials = newSeq[IdentityCredential]()
|
||||
|
||||
for i in 0..groupKeys.len-1:
|
||||
try:
|
||||
let
|
||||
idTrapdoor = IdentityTrapdoor(@(hexToUint[CredentialByteSize](groupKeys[i][0]).toBytesLE()))
|
||||
idNullifier = IdentityNullifier(@(hexToUint[CredentialByteSize](groupKeys[i][1]).toBytesLE()))
|
||||
idSecretHash = IdentitySecretHash(@(hexToUint[CredentialByteSize](groupKeys[i][2]).toBytesLE()))
|
||||
idCommitment = IDCommitment(@(hexToUint[CredentialByteSize](groupKeys[i][3]).toBytesLE()))
|
||||
groupIdCredentials.add(IdentityCredential(idTrapdoor: idTrapdoor, idNullifier: idNullifier, idSecretHash: idSecretHash,
|
||||
idCommitment: idCommitment))
|
||||
except ValueError as err:
|
||||
warn "could not convert the group key to bytes", err = err.msg
|
||||
return err("could not convert the group key to bytes: " & err.msg)
|
||||
return ok(groupIdCredentials)
|
||||
|
||||
proc toEpoch*(t: uint64): Epoch =
|
||||
## converts `t` to `Epoch` in little-endian order
|
||||
let bytes = toBytes(t, Endianness.littleEndian)
|
||||
|
@ -81,7 +81,7 @@ proc createRLNInstance*(d: int = MerkleTreeDepth): RLNResult =
|
||||
proc sha256*(data: openArray[byte]): MerkleNode =
|
||||
## a thin layer on top of the Nim wrapper of the sha256 hasher
|
||||
debug "sha256 hash input", hashhex = data.toHex()
|
||||
var lenPrefData = appendLength(data)
|
||||
var lenPrefData = encodeLengthPrefix(data)
|
||||
var
|
||||
hashInputBuffer = lenPrefData.toBuffer()
|
||||
outputBuffer: Buffer # will holds the hash output
|
||||
@ -209,7 +209,7 @@ proc insertMembers*(rlnInstance: ptr RLN,
|
||||
## Note: This proc is atomic, i.e., if any of the insertions fails, all the previous insertions are rolled back
|
||||
|
||||
# serialize the idComms
|
||||
let idCommsBytes = serializeIdCommitments(idComms)
|
||||
let idCommsBytes = serialize(idComms)
|
||||
|
||||
var idCommsBuffer = idCommsBytes.toBuffer()
|
||||
let idCommsBufferPtr = addr idCommsBuffer
|
||||
|
Loading…
x
Reference in New Issue
Block a user