From c222d83bcc481445442e7929285352d0ef168ca7 Mon Sep 17 00:00:00 2001 From: Sanaz Taheri Boshrooyeh <35961250+staheri14@users.noreply.github.com> Date: Tue, 24 Aug 2021 12:25:29 -0700 Subject: [PATCH] Enables passing RLN object across different function calls (#705) * tests rln instance as pointer * test insertion * tests deletion * tests proof generation and verification * updates rln instance type and the rln api * deletes old API * removes temporary tests * deletes unused codes * Delete settings.json * reverts the changes in tests v2 * removes an old comment --- tests/v2/test_waku_rln_relay.nim | 115 ++++++++---------- waku/v2/node/wakunode2.nim | 8 +- waku/v2/protocol/waku_rln_relay/rln.nim | 19 +-- .../waku_rln_relay/waku_rln_relay_types.nim | 3 +- .../waku_rln_relay/waku_rln_relay_utils.nim | 17 +-- 5 files changed, 76 insertions(+), 86 deletions(-) diff --git a/tests/v2/test_waku_rln_relay.nim b/tests/v2/test_waku_rln_relay.nim index 54d70b3e1..465f757df 100644 --- a/tests/v2/test_waku_rln_relay.nim +++ b/tests/v2/test_waku_rln_relay.nim @@ -180,13 +180,12 @@ procSuite "Waku rln relay": await web3.close() # create an RLN instance - var - ctx = RLN[Bn256]() - ctxPtr = addr(ctx) - doAssert(createRLNInstance(32, ctxPtr)) + var rlnInstance = createRLNInstance(32) + check: + rlnInstance.isOk == true # generate the membership keys - let membershipKeyPair = membershipKeyGen(ctxPtr) + let membershipKeyPair = membershipKeyGen(rlnInstance.value) check: membershipKeyPair.isSome @@ -242,13 +241,9 @@ suite "Waku rln relay": # check the parameters.key is not empty pbytes.len != 0 - # ctx holds the information that is going to be used for the key generation var - obj = RLN[Bn256]() - objPtr = addr(obj) - objptrptr = addr(objPtr) - ctx = objptrptr - let res = new_circuit_from_params(merkleDepth, addr parametersBuffer, ctx) + rlnInstance: RLN[Bn256] + let res = new_circuit_from_params(merkleDepth, addr parametersBuffer, addr rlnInstance) check: # check whether the circuit parameters are generated successfully res == true @@ -257,7 +252,7 @@ suite "Waku rln relay": var keysBuffer : Buffer keysBufferPtr = addr(keysBuffer) - done = key_gen(ctx[], keysBufferPtr) + done = key_gen(rlnInstance, keysBufferPtr) check: # check whether the keys are generated successfully done == true @@ -271,12 +266,11 @@ suite "Waku rln relay": test "membership Key Gen": # create an RLN instance - var - ctx = RLN[Bn256]() - ctxPtr = addr(ctx) - doAssert(createRLNInstance(32, ctxPtr)) + var rlnInstance = createRLNInstance(32) + check: + rlnInstance.isOk == true - var key = membershipKeyGen(ctxPtr) + var key = membershipKeyGen(rlnInstance.value) var empty : array[32,byte] check: key.isSome @@ -289,16 +283,15 @@ suite "Waku rln relay": test "get_root Nim binding": # create an RLN instance which also includes an empty Merkle tree - var - ctx = RLN[Bn256]() - ctxPtr = addr(ctx) - doAssert(createRLNInstance(32, ctxPtr)) + var rlnInstance = createRLNInstance(32) + check: + rlnInstance.isOk == true # read the Merkle Tree root var root1 {.noinit.} : Buffer = Buffer() rootPtr1 = addr(root1) - get_root_successful1 = get_root(ctxPtr, rootPtr1) + get_root_successful1 = get_root(rlnInstance.value, rootPtr1) doAssert(get_root_successful1) doAssert(root1.len == 32) @@ -306,7 +299,7 @@ suite "Waku rln relay": var root2 {.noinit.} : Buffer = Buffer() rootPtr2 = addr(root2) - get_root_successful2 = get_root(ctxPtr, rootPtr2) + get_root_successful2 = get_root(rlnInstance.value, rootPtr2) doAssert(get_root_successful2) doAssert(root2.len == 32) @@ -321,77 +314,74 @@ suite "Waku rln relay": test "update_next_member Nim Wrapper": # create an RLN instance which also includes an empty Merkle tree - var - ctx = RLN[Bn256]() - ctxPtr = addr(ctx) - doAssert(createRLNInstance(32, ctxPtr)) + var rlnInstance = createRLNInstance(32) + check: + rlnInstance.isOk == true # generate a key pair - var keypair = membershipKeyGen(ctxPtr) + var keypair = membershipKeyGen(rlnInstance.value) doAssert(keypair.isSome()) var pkBuffer = Buffer(`ptr`: addr(keypair.get().publicKey[0]), len: 32) let pkBufferPtr = addr pkBuffer # add the member to the tree - var member_is_added = update_next_member(ctxPtr, pkBufferPtr) + var member_is_added = update_next_member(rlnInstance.value, pkBufferPtr) check: member_is_added == true test "delete_member Nim wrapper": # create an RLN instance which also includes an empty Merkle tree - var - ctx = RLN[Bn256]() - ctxPtr = addr(ctx) - doAssert(createRLNInstance(32, ctxPtr)) + var rlnInstance = createRLNInstance(32) + check: + rlnInstance.isOk == true # delete the first member var deleted_member_index = uint(0) - let deletion_success = delete_member(ctxPtr, deleted_member_index) + let deletion_success = delete_member(rlnInstance.value, deleted_member_index) doAssert(deletion_success) test "Merkle tree consistency check between deletion and insertion": # create an RLN instance - var - ctx = RLN[Bn256]() - ctxPtr = addr(ctx) - doAssert(createRLNInstance(32, ctxPtr)) + var rlnInstance = createRLNInstance(32) + check: + rlnInstance.isOk == true # read the Merkle Tree root var root1 {.noinit.} : Buffer = Buffer() rootPtr1 = addr(root1) - get_root_successful1 = get_root(ctxPtr, rootPtr1) + get_root_successful1 = get_root(rlnInstance.value, rootPtr1) doAssert(get_root_successful1) doAssert(root1.len == 32) # generate a key pair - var keypair = membershipKeyGen(ctxPtr) + var keypair = membershipKeyGen(rlnInstance.value) doAssert(keypair.isSome()) var pkBuffer = Buffer(`ptr`: addr(keypair.get().publicKey[0]), len: 32) let pkBufferPtr = addr pkBuffer # add the member to the tree - var member_is_added = update_next_member(ctxPtr, pkBufferPtr) + var member_is_added = update_next_member(rlnInstance.value, pkBufferPtr) doAssert(member_is_added) # read the Merkle Tree root after insertion var root2 {.noinit.} : Buffer = Buffer() rootPtr2 = addr(root2) - get_root_successful2 = get_root(ctxPtr, rootPtr2) + get_root_successful2 = get_root(rlnInstance.value, rootPtr2) doAssert(get_root_successful2) doAssert(root2.len == 32) # delete the first member var deleted_member_index = uint(0) - let deletion_success = delete_member(ctxPtr, deleted_member_index) + let deletion_success = delete_member(rlnInstance.value, deleted_member_index) doAssert(deletion_success) # read the Merkle Tree root after the deletion var root3 {.noinit.} : Buffer = Buffer() rootPtr3 = addr(root3) - get_root_successful3 = get_root(ctxPtr, rootPtr3) + get_root_successful3 = get_root(rlnInstance.value, rootPtr3) doAssert(get_root_successful3) doAssert(root3.len == 32) @@ -415,11 +405,10 @@ suite "Waku rln relay": doAssert(rootHex1 == rootHex3) test "hash Nim Wrappers": # create an RLN instance - var - ctx = RLN[Bn256]() - ctxPtr = addr(ctx) - doAssert(createRLNInstance(30, ctxPtr)) - + var rlnInstance = createRLNInstance(32) + check: + rlnInstance.isOk == true + # prepare the input var hashInput : array[32, byte] @@ -435,7 +424,7 @@ suite "Waku rln relay": outputBuffer: Buffer numOfInputs = 1.uint # the number of hash inputs that can be 1 or 2 - let hashSuccess = hash(ctxPtr, addr hashInputBuffer, numOfInputs, addr outputBuffer) + let hashSuccess = hash(rlnInstance.value, addr hashInputBuffer, numOfInputs, addr outputBuffer) doAssert(hashSuccess) let outputArr = cast[ptr array[32,byte]](outputBuffer.`ptr`)[] doAssert("53a6338cdbf02f0563cec1898e354d0d272c8f98b606c538945c6f41ef101828" == outputArr.toHex()) @@ -448,15 +437,15 @@ suite "Waku rln relay": test "generate_proof and verify Nim Wrappers": # create an RLN instance - var - ctx = RLN[Bn256]() - ctxPtr = addr(ctx) # check if the rln instance is created successfully - doAssert(createRLNInstance(32, ctxPtr)) + var rlnInstance = createRLNInstance(32) + check: + rlnInstance.isOk == true + # create the membership key - var auth = membershipKeyGen(ctxPtr) + var auth = membershipKeyGen(rlnInstance.value) var skBuffer = Buffer(`ptr`: addr(auth.get().secretKey[0]), len: 32) # peer's index in the Merkle Tree @@ -471,11 +460,11 @@ suite "Waku rln relay": if (i == index): # insert the current peer's pk var pkBuffer = Buffer(`ptr`: addr(auth.get().publicKey[0]), len: 32) - member_is_added = update_next_member(ctxPtr, addr pkBuffer) + member_is_added = update_next_member(rlnInstance.value, addr pkBuffer) else: - var memberKeys = membershipKeyGen(ctxPtr) + var memberKeys = membershipKeyGen(rlnInstance.value) var pkBuffer = Buffer(`ptr`: addr(memberKeys.get().publicKey[0]), len: 32) - member_is_added = update_next_member(ctxPtr, addr pkBuffer) + member_is_added = update_next_member(rlnInstance.value, addr pkBuffer) # check the member is added doAssert(member_is_added) @@ -505,7 +494,7 @@ suite "Waku rln relay": # generate the proof var proof: Buffer - let proofIsSuccessful = generate_proof(ctxPtr, addr inputBuffer, addr authObj, addr proof) + let proofIsSuccessful = generate_proof(rlnInstance.value, addr inputBuffer, addr authObj, addr proof) # check whether the generate_proof call is done successfully doAssert(proofIsSuccessful) var proofValue = cast[ptr array[416,byte]] (proof.`ptr`) @@ -537,7 +526,7 @@ suite "Waku rln relay": debug "nullifier", nullifier var f = 0.uint32 - let verifyIsSuccessful = verify(ctxPtr, addr proof, addr f) + let verifyIsSuccessful = verify(rlnInstance.value, addr proof, addr f) doAssert(verifyIsSuccessful) # f = 0 means the proof is verified doAssert(f == 0) @@ -547,13 +536,13 @@ suite "Waku rln relay": var badIndex = 8 var badAuthObj: Auth = Auth(secret_buffer: addr skBuffer, index: uint(badIndex)) var badProof: Buffer - let badProofIsSuccessful = generate_proof(ctxPtr, addr inputBuffer, addr badAuthObj, addr badProof) + let badProofIsSuccessful = generate_proof(rlnInstance.value, addr inputBuffer, addr badAuthObj, addr badProof) # check whether the generate_proof call is done successfully doAssert(badProofIsSuccessful) var badF = 0.uint32 - let badVerifyIsSuccessful = verify(ctxPtr, addr badProof, addr badF) + let badVerifyIsSuccessful = verify(rlnInstance.value, addr badProof, addr badF) doAssert(badVerifyIsSuccessful) # badF=1 means the proof is not verified # verification of the bad proof should fail - doAssert(badF == 1) + doAssert(badF == 1) \ No newline at end of file diff --git a/waku/v2/node/wakunode2.nim b/waku/v2/node/wakunode2.nim index 441591a0d..9a16dc8ab 100644 --- a/waku/v2/node/wakunode2.nim +++ b/waku/v2/node/wakunode2.nim @@ -419,13 +419,11 @@ when defined(rln): doAssert(membershipContractAddress.isSome()) # create an RLN instance - var - ctx = RLN[Bn256]() - ctxPtr = addr(ctx) - doAssert(createRLNInstance(32, ctxPtr)) + var rlnInstance = createRLNInstance(32) + doAssert(rlnInstance.isOk) # generate the membership keys - let membershipKeyPair = membershipKeyGen(ctxPtr) + let membershipKeyPair = membershipKeyGen(rlnInstance.value) # check whether keys are generated doAssert(membershipKeyPair.isSome()) debug "the membership key for the rln relay is generated" diff --git a/waku/v2/protocol/waku_rln_relay/rln.nim b/waku/v2/protocol/waku_rln_relay/rln.nim index 1d6fea62a..297ec7d24 100644 --- a/waku/v2/protocol/waku_rln_relay/rln.nim +++ b/waku/v2/protocol/waku_rln_relay/rln.nim @@ -30,23 +30,24 @@ type Auth* = object #------------------------------ Merkle Tree operations ----------------------------------------- -proc update_next_member*(ctx: ptr RLN[Bn256], +proc update_next_member*(ctx: RLN[Bn256], input_buffer: ptr Buffer): bool {.importc: "update_next_member".} -proc delete_member*(ctx: ptr RLN[Bn256], index: uint): bool {.importc: "delete_member".} +proc delete_member*(ctx: RLN[Bn256], index: uint): bool {.importc: "delete_member".} + +proc get_root*(ctx: RLN[Bn256], output_buffer: ptr Buffer): bool {.importc: "get_root".} -proc get_root*(ctx: ptr RLN[Bn256], output_buffer: ptr Buffer): bool {.importc: "get_root".} #---------------------------------------------------------------------------------------------- #-------------------------------- zkSNARKs operations ----------------------------------------- -proc key_gen*(ctx: ptr RLN[Bn256], keypair_buffer: ptr Buffer): bool {.importc: "key_gen".} +proc key_gen*(ctx: RLN[Bn256], keypair_buffer: ptr Buffer): bool {.importc: "key_gen".} -proc generate_proof*(ctx: ptr RLN[Bn256], +proc generate_proof*(ctx: RLN[Bn256], input_buffer: ptr Buffer, auth: ptr Auth, output_buffer: ptr Buffer): bool {.importc: "generate_proof".} -proc verify*(ctx: ptr RLN[Bn256], +proc verify*(ctx: RLN[Bn256], proof_buffer: ptr Buffer, result_ptr: ptr uint32): bool {.importc: "verify".} #---------------------------------------------------------------------------------------------- @@ -54,9 +55,9 @@ proc verify*(ctx: ptr RLN[Bn256], proc new_circuit_from_params*(merkle_depth: uint, parameters_buffer: ptr Buffer, - ctx: ptr (ptr RLN[Bn256])): bool {.importc: "new_circuit_from_params".} - -proc hash*(ctx: ptr RLN[Bn256], + ctx: ptr RLN[Bn256]): bool {.importc: "new_circuit_from_params".} + +proc hash*(ctx: RLN[Bn256], inputs_buffer: ptr Buffer, input_len: uint, output_buffer: ptr Buffer): bool {.importc: "hash".} diff --git a/waku/v2/protocol/waku_rln_relay/waku_rln_relay_types.nim b/waku/v2/protocol/waku_rln_relay/waku_rln_relay_types.nim index 5a444092d..08cf3d42e 100644 --- a/waku/v2/protocol/waku_rln_relay/waku_rln_relay_types.nim +++ b/waku/v2/protocol/waku_rln_relay/waku_rln_relay_types.nim @@ -8,7 +8,8 @@ import ## 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] {.incompleteStruct.} = object +type RLN*[E] = pointer + # Custom data types defined for waku rln relay ------------------------- type MembershipKeyPair* = object diff --git a/waku/v2/protocol/waku_rln_relay/waku_rln_relay_utils.nim b/waku/v2/protocol/waku_rln_relay/waku_rln_relay_utils.nim index 810e3eea0..0cce6b8e9 100644 --- a/waku/v2/protocol/waku_rln_relay/waku_rln_relay_utils.nim +++ b/waku/v2/protocol/waku_rln_relay/waku_rln_relay_utils.nim @@ -3,6 +3,7 @@ import chronicles, options, chronos, stint, web3, + stew/results, stew/byteutils, rln, waku_rln_relay_types @@ -10,19 +11,20 @@ import logScope: topics = "wakurlnrelayutils" +type RLNResult* = Result[RLN[Bn256], string] # membership contract interface contract(MembershipContract): # TODO define a return type of bool for register method to signify a successful registration proc register(pubkey: Uint256) # external payable -proc createRLNInstance*(d: int, ctxPtr: var ptr RLN[Bn256]): bool +proc createRLNInstance*(d: int): RLNResult {.raises: [Defect, IOError].} = ## generates an instance of RLN ## An RLN instance supports both zkSNARKs logics and Merkle tree data structure and operations ## d indicates the depth of Merkle tree var - ctxPtrPtr = addr(ctxPtr) + rlnInstance: RLN[Bn256] merkleDepth: csize_t = uint(d) # parameters.key contains the parameters related to the Poseidon hasher # to generate this file, clone this repo https://github.com/kilic/rln @@ -37,17 +39,17 @@ proc createRLNInstance*(d: int, ctxPtr: var ptr RLN[Bn256]): bool # check the parameters.key is not empty if (pbytes.len == 0): debug "error in parameters.key" - return false + return err("error in parameters.key") # create an instance of RLN - let res = new_circuit_from_params(merkleDepth, addr parametersBuffer, ctxPtrPtr) + let res = new_circuit_from_params(merkleDepth, addr parametersBuffer, addr rlnInstance) # check whether the circuit parameters are generated successfully if (res == false): debug "error in parameters generation" - return false - return true + return err("error in parameters generation") + return ok(rlnInstance) -proc membershipKeyGen*(ctxPtr: ptr RLN[Bn256]): Option[MembershipKeyPair] = +proc membershipKeyGen*(ctxPtr: RLN[Bn256]): Option[MembershipKeyPair] = ## generates a MembershipKeyPair that can be used for the registration into the rln membership contract # keysBufferPtr will hold the generated key pairs i.e., secret and public keys @@ -79,7 +81,6 @@ proc membershipKeyGen*(ctxPtr: ptr RLN[Bn256]): Option[MembershipKeyPair] = return some(keypair) - proc register*(rlnPeer: WakuRLNRelay): Future[bool] {.async.} = ## registers the public key of the rlnPeer which is rlnPeer.membershipKeyPair.publicKey ## into the membership contract whose address is in rlnPeer.membershipContractAddress