feat: isolate generateProof fuction till confidence

This commit is contained in:
darshankabariya 2025-03-12 11:54:56 +05:30
parent cadf86d060
commit 3b5ac7d3e4
3 changed files with 133 additions and 93 deletions

View File

@ -333,7 +333,7 @@ suite "Onchain group manager":
debug "epoch in bytes", epochHex = epoch.inHex()
# generate proof
let validProofRes = await manager.generateProof(
let validProofRes = manager.generateProof(
data = messageBytes, epoch = epoch, messageId = MessageId(1)
)
@ -367,7 +367,7 @@ suite "Onchain group manager":
debug "epoch in bytes", epochHex = epoch.inHex()
# generate proof
let proofResult = await manager.generateProof(
let proofResult = manager.generateProof(
data = messageBytes, epoch = epoch, messageId = MessageId(0)
)
let validProof = proofResult.valueOr:
@ -411,10 +411,9 @@ suite "Onchain group manager":
debug "epoch in bytes", epochHex = epoch.inHex()
# generate proof
let proofResult = await manager.generateProof(
let validProof = manager.generateProof(
data = messageBytes, epoch = epoch, messageId = MessageId(0)
)
let validProof = proofResult.valueOr:
).valueOr
raiseAssert $error
# verify the proof (should be true)
@ -456,7 +455,7 @@ suite "Onchain group manager":
debug "epoch in bytes", epochHex = epoch.inHex()
# generate proof
let invalidProofRes = await manager.generateProof(
let invalidProofRes = manager.generateProof(
data = messageBytes, epoch = epoch, messageId = MessageId(0)
)

View File

@ -239,93 +239,6 @@ method withdrawBatch*(
): Future[void] {.async: (raises: [Exception]).} =
initializedGuard(g)
method generateProof*(
g: OnchainGroupManager,
data: seq[byte],
epoch: Epoch,
messageId: MessageId,
rlnIdentifier = DefaultRlnIdentifier,
): Future[GroupManagerResult[RateLimitProof]] {.async, gcsafe, raises: [].} =
## Generates an RLN proof using the cached Merkle proof and custom witness
# Ensure identity credentials and membership index are set
if g.idCredentials.isNone():
return err("identity credentials are not set")
if g.membershipIndex.isNone():
return err("membership index is not set")
if g.userMessageLimit.isNone():
return err("user message limit is not set")
# Retrieve the cached Merkle proof for the membership index
let index = stuint(g.membershipIndex.get(), 256)
if not g.merkleProofsByIndex.hasKey(index):
await g.fetchMerkleProof(index)
let merkle_proof = g.merkleProofsByIndex[index]
if merkle_proof.len == 0:
return err("Merkle proof not found")
# Prepare the witness
let witness = Witness(
identity_secret: g.idCredentials.get().idSecretHash,
identity_nullifier: g.idCredentials.get().idNullifier,
merkle_proof: merkleProof,
external_nullifier: epoch,
signal: data,
message_id: messageId,
rln_identifier: rlnIdentifier,
)
let serializedWitness = serialize(witness)
var inputBuffer = toBuffer(serializedWitness)
# Generate the proof using the new zerokit API
var outputBuffer: Buffer
let success =
generate_proof_with_witness(g.rlnInstance, addr inputBuffer, addr outputBuffer)
if not success:
return err("Failed to generate proof")
# Parse the proof into a RateLimitProof object
var proofValue = cast[ptr array[320, byte]](outputBuffer.`ptr`)
let proofBytes: array[320, byte] = proofValue[]
debug "proof content", proofHex = proofValue[].toHex
## parse the proof as [ proof<128> | root<32> | external_nullifier<32> | share_x<32> | share_y<32> | nullifier<32> ]
let
proofOffset = 128
rootOffset = proofOffset + 32
externalNullifierOffset = rootOffset + 32
shareXOffset = externalNullifierOffset + 32
shareYOffset = shareXOffset + 32
nullifierOffset = shareYOffset + 32
var
zkproof: ZKSNARK
proofRoot, shareX, shareY: MerkleNode
externalNullifier: ExternalNullifier
nullifier: Nullifier
discard zkproof.copyFrom(proofBytes[0 .. proofOffset - 1])
discard proofRoot.copyFrom(proofBytes[proofOffset .. rootOffset - 1])
discard
externalNullifier.copyFrom(proofBytes[rootOffset .. externalNullifierOffset - 1])
discard shareX.copyFrom(proofBytes[externalNullifierOffset .. shareXOffset - 1])
discard shareY.copyFrom(proofBytes[shareXOffset .. shareYOffset - 1])
discard nullifier.copyFrom(proofBytes[shareYOffset .. nullifierOffset - 1])
# Create the RateLimitProof object
let output = RateLimitProof(
proof: zkproof,
merkleRoot: proofRoot,
externalNullifier: externalNullifier,
epoch: epoch,
rlnIdentifier: rlnIdentifier,
shareX: shareX,
shareY: shareY,
nullifier: nullifier,
)
return ok(output)
# TODO: after slashing is enabled on the contract, use atomicBatch internally
proc parseEvent(

View File

@ -0,0 +1,128 @@
{.push raises: [].}
import
std/[tables, options],
chronos,
web3,
stint,
../on_chain/group_manager as onchain,
../../rln,
../../conversion_utils
logScope:
topics = "waku rln_relay onchain_sync_group_manager"
type OnChainSyncGroupManager* = ref object of onchain.OnchainGroupManager
# Cache for merkle proofs by index
merkleProofsByIndex*: Table[Uint256, seq[Uint256]]
method generateProof*(
g: OnChainSyncGroupManager,
data: seq[byte],
epoch: Epoch,
messageId: MessageId,
rlnIdentifier = DefaultRlnIdentifier,
): Future[GroupManagerResult[RateLimitProof]] {.async.} =
## Generates an RLN proof using the cached Merkle proof and custom witness
# Ensure identity credentials and membership index are set
if g.idCredentials.isNone():
return err("identity credentials are not set")
if g.membershipIndex.isNone():
return err("membership index is not set")
if g.userMessageLimit.isNone():
return err("user message limit is not set")
# Retrieve the cached Merkle proof for the membership index
let index = stuint(g.membershipIndex.get(), 256)
if not g.merkleProofsByIndex.hasKey(index):
try:
let merkleProofInvocation = g.wakuRlnContract.get().merkleProofElements(index)
let merkleProof = await merkleProofInvocation.call()
g.merkleProofsByIndex[index] = merkleProof
except CatchableError:
return err("Failed to fetch merkle proof: " & getCurrentExceptionMsg())
let merkleProof = g.merkleProofsByIndex[index]
if merkleProof.len == 0:
return err("Merkle proof not found")
# Prepare the witness
let witness = Witness(
identity_secret: g.idCredentials.get().idSecretHash,
identity_nullifier: g.idCredentials.get().idNullifier,
merkle_proof: merkleProof,
external_nullifier: epoch,
signal: data,
message_id: messageId,
rln_identifier: rlnIdentifier,
)
let serializedWitness = serialize(witness)
var inputBuffer = toBuffer(serializedWitness)
# Generate the proof using the zerokit API
var outputBuffer: Buffer
let success =
generate_proof_with_witness(g.rlnInstance, addr inputBuffer, addr outputBuffer)
if not success:
return err("Failed to generate proof")
# Parse the proof into a RateLimitProof object
var proofValue = cast[ptr array[320, byte]](outputBuffer.`ptr`)
let proofBytes: array[320, byte] = proofValue[]
## parse the proof as [ proof<128> | root<32> | external_nullifier<32> | share_x<32> | share_y<32> | nullifier<32> ]
let
proofOffset = 128
rootOffset = proofOffset + 32
externalNullifierOffset = rootOffset + 32
shareXOffset = externalNullifierOffset + 32
shareYOffset = shareXOffset + 32
nullifierOffset = shareYOffset + 32
var
zkproof: ZKSNARK
proofRoot, shareX, shareY: MerkleNode
externalNullifier: ExternalNullifier
nullifier: Nullifier
discard zkproof.copyFrom(proofBytes[0 .. proofOffset - 1])
discard proofRoot.copyFrom(proofBytes[proofOffset .. rootOffset - 1])
discard
externalNullifier.copyFrom(proofBytes[rootOffset .. externalNullifierOffset - 1])
discard shareX.copyFrom(proofBytes[externalNullifierOffset .. shareXOffset - 1])
discard shareY.copyFrom(proofBytes[shareXOffset .. shareYOffset - 1])
discard nullifier.copyFrom(proofBytes[shareYOffset .. nullifierOffset - 1])
# Create the RateLimitProof object
let output = RateLimitProof(
proof: zkproof,
merkleRoot: proofRoot,
externalNullifier: externalNullifier,
epoch: epoch,
rlnIdentifier: rlnIdentifier,
shareX: shareX,
shareY: shareY,
nullifier: nullifier,
)
return ok(output)
method register*(
g: OnChainSyncGroupManager,
identityCredential: IdentityCredential,
userMessageLimit: UserMessageLimit,
): Future[void] {.async: (raises: [Exception]).} =
# Call parent's register method first
await procCall onchain.OnchainGroupManager(g).register(
identityCredential, userMessageLimit
)
# After registration, fetch and cache the merkle proof
let membershipIndex = g.membershipIndex.get()
try:
let merkleProofInvocation =
g.wakuRlnContract.get().merkleProofElements(stuint(membershipIndex, 256))
let merkleProof = await merkleProofInvocation.call()
g.merkleProofsByIndex[stuint(membershipIndex, 256)] = merkleProof
except CatchableError:
error "Failed to fetch initial merkle proof: " & getCurrentExceptionMsg()