mirror of
https://github.com/logos-messaging/logos-messaging-nim.git
synced 2026-02-26 16:53:09 +00:00
feat: isolate generateProof fuction till confidence
This commit is contained in:
parent
8869efe03f
commit
f22da1d36a
@ -330,7 +330,7 @@ suite "Onchain group manager":
|
|||||||
debug "epoch in bytes", epochHex = epoch.inHex()
|
debug "epoch in bytes", epochHex = epoch.inHex()
|
||||||
|
|
||||||
# generate proof
|
# generate proof
|
||||||
let validProofRes = await manager.generateProof(
|
let validProofRes = manager.generateProof(
|
||||||
data = messageBytes, epoch = epoch, messageId = MessageId(1)
|
data = messageBytes, epoch = epoch, messageId = MessageId(1)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -364,7 +364,7 @@ suite "Onchain group manager":
|
|||||||
debug "epoch in bytes", epochHex = epoch.inHex()
|
debug "epoch in bytes", epochHex = epoch.inHex()
|
||||||
|
|
||||||
# generate proof
|
# generate proof
|
||||||
let proofResult = await manager.generateProof(
|
let proofResult = manager.generateProof(
|
||||||
data = messageBytes, epoch = epoch, messageId = MessageId(0)
|
data = messageBytes, epoch = epoch, messageId = MessageId(0)
|
||||||
)
|
)
|
||||||
let validProof = proofResult.valueOr:
|
let validProof = proofResult.valueOr:
|
||||||
@ -408,10 +408,9 @@ suite "Onchain group manager":
|
|||||||
debug "epoch in bytes", epochHex = epoch.inHex()
|
debug "epoch in bytes", epochHex = epoch.inHex()
|
||||||
|
|
||||||
# generate proof
|
# generate proof
|
||||||
let proofResult = await manager.generateProof(
|
let validProof = manager.generateProof(
|
||||||
data = messageBytes, epoch = epoch, messageId = MessageId(0)
|
data = messageBytes, epoch = epoch, messageId = MessageId(0)
|
||||||
)
|
).valueOr
|
||||||
let validProof = proofResult.valueOr:
|
|
||||||
raiseAssert $error
|
raiseAssert $error
|
||||||
|
|
||||||
# verify the proof (should be true)
|
# verify the proof (should be true)
|
||||||
@ -453,7 +452,7 @@ suite "Onchain group manager":
|
|||||||
debug "epoch in bytes", epochHex = epoch.inHex()
|
debug "epoch in bytes", epochHex = epoch.inHex()
|
||||||
|
|
||||||
# generate proof
|
# generate proof
|
||||||
let invalidProofRes = await manager.generateProof(
|
let invalidProofRes = manager.generateProof(
|
||||||
data = messageBytes, epoch = epoch, messageId = MessageId(0)
|
data = messageBytes, epoch = epoch, messageId = MessageId(0)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@ -239,93 +239,6 @@ method withdrawBatch*(
|
|||||||
): Future[void] {.async: (raises: [Exception]).} =
|
): Future[void] {.async: (raises: [Exception]).} =
|
||||||
initializedGuard(g)
|
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
|
# TODO: after slashing is enabled on the contract, use atomicBatch internally
|
||||||
|
|
||||||
proc parseEvent(
|
proc parseEvent(
|
||||||
|
|||||||
@ -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()
|
||||||
Loading…
x
Reference in New Issue
Block a user