mirror of
https://github.com/logos-storage/logos-storage-nim.git
synced 2026-01-03 22:13:12 +00:00
wip
This commit is contained in:
parent
f408b78ab0
commit
294a1f7105
@ -39,22 +39,21 @@ type
|
||||
backendCfg: ptr CircomBn254Cfg
|
||||
vkp*: ptr CircomKey
|
||||
taskpool: Taskpool
|
||||
lock: ptr Lock
|
||||
|
||||
NormalizedProofInputs*[H] {.borrow: `.`.} = distinct ProofInputs[H]
|
||||
|
||||
ProveTask = object
|
||||
circom: ptr CircomCompat
|
||||
ctx: ptr CircomCompatCtx
|
||||
proof: ptr Proof
|
||||
success: Atomic[bool]
|
||||
proofPtr: ProofPtr
|
||||
res: Atomic[int32]
|
||||
signal: ThreadSignalPtr
|
||||
|
||||
VerifyTask = object
|
||||
proof: ptr CircomProof
|
||||
vkp: ptr CircomKey
|
||||
inputs: ptr CircomInputs
|
||||
success: VerifyResult
|
||||
res: Atomic[int32]
|
||||
signal: ThreadSignalPtr
|
||||
|
||||
func normalizeInput*[H](
|
||||
@ -98,33 +97,16 @@ proc release*(self: CircomCompat) =
|
||||
if not isNil(self.vkp):
|
||||
self.vkp.unsafeAddr.release_key()
|
||||
|
||||
if not isNil(self.lock):
|
||||
deinitLock(self.lock[]) # Cleanup the lock
|
||||
dealloc(self.lock) # Free the memory
|
||||
|
||||
proc circomProveTask(task: ptr ProveTask) {.gcsafe.} =
|
||||
withLock task[].circom.lock[]:
|
||||
defer:
|
||||
discard task[].signal.fireSync()
|
||||
defer:
|
||||
discard task[].signal.fireSync()
|
||||
|
||||
var proofPtr: ptr Proof = nil
|
||||
try:
|
||||
if (
|
||||
let res = task.circom.backendCfg.prove_circuit(task.ctx, proofPtr.addr)
|
||||
res != ERR_OK
|
||||
) or proofPtr == nil:
|
||||
task.success.store(false)
|
||||
return
|
||||
|
||||
copyProof(task.proof, proofPtr[])
|
||||
task.success.store(true)
|
||||
finally:
|
||||
if proofPtr != nil:
|
||||
proofPtr.addr.release_proof()
|
||||
let res = task.circom.backendCfg.prove_circuit(task[].ctx, task[].proofPtr.addr)
|
||||
task.res.store(res)
|
||||
|
||||
proc asyncProve*[H](
|
||||
self: CircomCompat, input: NormalizedProofInputs[H], proof: ptr Proof
|
||||
): Future[?!void] {.async.} =
|
||||
self: CircomCompat, input: NormalizedProofInputs[H]
|
||||
): Future[?!Proof] {.async.} =
|
||||
doAssert input.samples.len == self.numSamples, "Number of samples does not match"
|
||||
|
||||
doAssert input.slotProof.len <= self.datasetDepth,
|
||||
@ -200,45 +182,45 @@ proc asyncProve*[H](
|
||||
ERR_OK:
|
||||
return failure("Failed to push cell data")
|
||||
|
||||
without threadPtr =? ThreadSignalPtr.new():
|
||||
without threadPtr =? ThreadSignalPtr.new().mapFailure, err:
|
||||
trace "Failed to create thread signal", err = err.msg
|
||||
return failure("Unable to create thread signal")
|
||||
|
||||
var task = ProveTask(circom: addr self, ctx: ctx, signal: threadPtr)
|
||||
|
||||
defer:
|
||||
threadPtr.close().expect("closing once works")
|
||||
|
||||
var task = ProveTask(circom: addr self, ctx: ctx, proof: proof, signal: threadPtr)
|
||||
|
||||
let taskPtr = addr task
|
||||
if task.proofPtr != nil:
|
||||
task.proofPtr.addr.release_proof()
|
||||
|
||||
doAssert task.circom.taskpool.numThreads > 1,
|
||||
"Must have at least one separate thread or signal will never be fired"
|
||||
task.circom.taskpool.spawn circomProveTask(taskPtr)
|
||||
task.circom.taskpool.spawn circomProveTask(addr task)
|
||||
let threadFut = threadPtr.wait()
|
||||
|
||||
if joinErr =? catch(await threadFut.join()).errorOption:
|
||||
if err =? catch(await noCancel threadFut).errorOption:
|
||||
trace "Failed to prove circuit", err = err.msg
|
||||
return failure(err)
|
||||
if joinErr of CancelledError:
|
||||
trace "Cancellation requested for proving circuit, re-raising"
|
||||
raise joinErr
|
||||
else:
|
||||
return failure(joinErr)
|
||||
|
||||
if not task.success.load():
|
||||
if task.res.load() != ERR_OK:
|
||||
return failure("Failed to prove circuit")
|
||||
|
||||
success()
|
||||
success(task.proofPtr[])
|
||||
|
||||
proc prove*[H](
|
||||
self: CircomCompat, input: ProofInputs[H]
|
||||
): Future[?!CircomProof] {.async, raises: [CancelledError].} =
|
||||
var proof = ProofPtr.new()
|
||||
defer:
|
||||
destroyProof(proof)
|
||||
|
||||
try:
|
||||
if error =? (await self.asyncProve(self.normalizeInput(input), proof)).errorOption:
|
||||
return failure(error)
|
||||
return success(deepCopy(proof)[])
|
||||
without proof =? (await self.asyncProve(self.normalizeInput(input))), err:
|
||||
trace "Failed to prove circuit", err = err.msg
|
||||
return failure(err)
|
||||
return success(proof)
|
||||
except CancelledError as exc:
|
||||
raise exc
|
||||
|
||||
@ -248,68 +230,62 @@ proc circomVerifyTask(task: ptr VerifyTask) {.gcsafe.} =
|
||||
discard task[].signal.fireSync()
|
||||
|
||||
let res = verify_circuit(task[].proof, task[].inputs, task[].vkp)
|
||||
if res == ERR_OK:
|
||||
task[].success[] = true
|
||||
elif res == ERR_FAILED_TO_VERIFY_PROOF:
|
||||
task[].success[] = false
|
||||
else:
|
||||
task[].success[] = false
|
||||
error "Failed to verify proof", errorCode = res
|
||||
task.res.store(res)
|
||||
|
||||
proc asyncVerify*[H](
|
||||
self: CircomCompat,
|
||||
proof: CircomProof,
|
||||
inputs: ProofInputs[H],
|
||||
success: VerifyResult,
|
||||
): Future[?!void] {.async.} =
|
||||
var proofPtr = unsafeAddr proof
|
||||
var inputs = inputs.toCircomInputs()
|
||||
self: CircomCompat, proof: CircomProof, inputs: ProofInputs[H]
|
||||
): Future[?!int32] {.async.} =
|
||||
var
|
||||
proofPtr = unsafeAddr proof
|
||||
inputs = inputs.toCircomInputs()
|
||||
|
||||
without threadPtr =? ThreadSignalPtr.new():
|
||||
without threadPtr =? ThreadSignalPtr.new().mapFailure, err:
|
||||
trace "Failed to create thread signal", err = err.msg
|
||||
return failure("Unable to create thread signal")
|
||||
|
||||
defer:
|
||||
threadPtr.close().expect("closing once works")
|
||||
inputs.releaseCircomInputs()
|
||||
|
||||
var task = VerifyTask(
|
||||
proof: proofPtr,
|
||||
vkp: self.vkp,
|
||||
inputs: addr inputs,
|
||||
success: success,
|
||||
signal: threadPtr,
|
||||
)
|
||||
|
||||
let taskPtr = addr task
|
||||
var task =
|
||||
VerifyTask(proof: proofPtr, vkp: self.vkp, inputs: addr inputs, signal: threadPtr)
|
||||
|
||||
doAssert self.taskpool.numThreads > 1,
|
||||
"Must have at least one separate thread or signal will never be fired"
|
||||
|
||||
self.taskpool.spawn circomVerifyTask(taskPtr)
|
||||
self.taskpool.spawn circomVerifyTask(addr task)
|
||||
|
||||
let threadFut = threadPtr.wait()
|
||||
|
||||
if joinErr =? catch(await threadFut.join()).errorOption:
|
||||
if err =? catch(await noCancel threadFut).errorOption:
|
||||
trace "Failed to verify proof", err = err.msg
|
||||
return failure(err)
|
||||
if joinErr of CancelledError:
|
||||
trace "Cancellation requested for verifying proof, re-raising"
|
||||
raise joinErr
|
||||
else:
|
||||
return failure(joinErr)
|
||||
|
||||
success()
|
||||
success(task.res.load())
|
||||
|
||||
proc verify*[H](
|
||||
self: CircomCompat, proof: CircomProof, inputs: ProofInputs[H]
|
||||
): Future[?!bool] {.async, raises: [CancelledError].} =
|
||||
## Verify a proof using a ctx
|
||||
##
|
||||
var res = VerifyResult.new()
|
||||
defer:
|
||||
destroyVerifyResult(res)
|
||||
try:
|
||||
if error =? (await self.asyncVerify(proof, inputs, res)).errorOption:
|
||||
return failure(error)
|
||||
return success(res[])
|
||||
without res =? (await self.asyncVerify(proof, inputs)), err:
|
||||
trace "Failed to verify proof", err = err.msg
|
||||
return failure(err)
|
||||
|
||||
case res
|
||||
of ERR_FAILED_TO_VERIFY_PROOF:
|
||||
return failure("Failed to verify proof")
|
||||
of ERR_OK:
|
||||
return success(true)
|
||||
else:
|
||||
return failure("Unknown error")
|
||||
except CancelledError as exc:
|
||||
raise exc
|
||||
|
||||
@ -325,11 +301,9 @@ proc init*(
|
||||
numSamples = DefaultSamplesNum,
|
||||
taskpool: Taskpool,
|
||||
): CircomCompat =
|
||||
# Allocate and initialize the lock
|
||||
var lockPtr = create(Lock) # Allocate memory for the lock
|
||||
initLock(lockPtr[]) # Initialize the lock
|
||||
|
||||
## Create a new ctx
|
||||
##
|
||||
|
||||
var cfg: ptr CircomBn254Cfg
|
||||
var zkey = if zkeyPath.len > 0: zkeyPath.cstring else: nil
|
||||
|
||||
@ -358,5 +332,4 @@ proc init*(
|
||||
backendCfg: cfg,
|
||||
vkp: vkpPtr,
|
||||
taskpool: taskpool,
|
||||
lock: lockPtr,
|
||||
)
|
||||
|
||||
@ -23,15 +23,8 @@ type
|
||||
CircomProof* = Proof
|
||||
CircomKey* = VerifyingKey
|
||||
CircomInputs* = Inputs
|
||||
VerifyResult* = ptr bool
|
||||
ProofPtr* = ptr Proof
|
||||
|
||||
proc new*(_: type ProofPtr): ProofPtr =
|
||||
cast[ptr Proof](allocShared0(sizeof(Proof)))
|
||||
|
||||
proc new*(_: type VerifyResult): VerifyResult =
|
||||
cast[ptr bool](allocShared0(sizeof(bool)))
|
||||
|
||||
proc toCircomInputs*(inputs: ProofInputs[Poseidon2Hash]): CircomInputs =
|
||||
var
|
||||
slotIndex = inputs.slotIndex.toF.toBytes.toArray32
|
||||
@ -61,26 +54,3 @@ func toG2*(g: CircomG2): G2Point =
|
||||
|
||||
func toGroth16Proof*(proof: CircomProof): Groth16Proof =
|
||||
Groth16Proof(a: proof.a.toG1, b: proof.b.toG2, c: proof.c.toG1)
|
||||
|
||||
proc destroyVerifyResult*(result: VerifyResult) =
|
||||
if result != nil:
|
||||
deallocShared(result)
|
||||
|
||||
proc destroyProof*(proof: ProofPtr) =
|
||||
if proof != nil:
|
||||
deallocShared(proof)
|
||||
|
||||
proc copyInto*(dest: var G1, src: G1) =
|
||||
copyMem(addr dest.x[0], addr src.x[0], 32)
|
||||
copyMem(addr dest.y[0], addr src.y[0], 32)
|
||||
|
||||
proc copyInto*(dest: var G2, src: G2) =
|
||||
for i in 0 .. 1:
|
||||
copyMem(addr dest.x[i][0], addr src.x[i][0], 32)
|
||||
copyMem(addr dest.y[i][0], addr src.y[i][0], 32)
|
||||
|
||||
proc copyProof*(dest: ptr Proof, src: Proof) =
|
||||
if not isNil(dest):
|
||||
copyInto(dest.a, src.a)
|
||||
copyInto(dest.b, src.b)
|
||||
copyInto(dest.c, src.c)
|
||||
|
||||
@ -69,6 +69,7 @@ suite "Test Prover":
|
||||
|
||||
let (inputs, proof) = (await prover.prove(1, verifiable, challenge)).tryGet
|
||||
|
||||
echo "Proof: ", proof
|
||||
check:
|
||||
(await prover.verify(proof, inputs)).tryGet == true
|
||||
|
||||
@ -111,7 +112,6 @@ suite "Test Prover":
|
||||
proveTasks.add(prover.prove(1, verifiable, challenge))
|
||||
|
||||
let proveResults = await allFinished(proveTasks)
|
||||
#
|
||||
for i in 0 ..< proveResults.len:
|
||||
var (inputs, proofs) = proveTasks[i].read().tryGet()
|
||||
verifyTasks.add(prover.verify(proofs, inputs))
|
||||
@ -134,35 +134,29 @@ suite "Test Prover":
|
||||
|
||||
let (inputs, proof) = (await prover.prove(1, verifiable, challenge)).tryGet
|
||||
|
||||
var cancelledProof = ProofPtr.new()
|
||||
defer:
|
||||
destroyProof(cancelledProof)
|
||||
|
||||
# call asyncProve and cancel the task
|
||||
let proveFut = backend.asyncProve(backend.normalizeInput(inputs), cancelledProof)
|
||||
let proveFut = backend.asyncProve(backend.normalizeInput(inputs))
|
||||
proveFut.cancel()
|
||||
|
||||
var cancelledProof: Proof
|
||||
try:
|
||||
discard await proveFut
|
||||
cancelledProof = (await proveFut).tryGet
|
||||
except CatchableError as exc:
|
||||
check exc of CancelledError
|
||||
finally:
|
||||
# validate the cancelledProof
|
||||
check:
|
||||
(await prover.verify(cancelledProof[], inputs)).tryGet == true
|
||||
|
||||
var verifyRes = VerifyResult.new()
|
||||
defer:
|
||||
destroyVerifyResult(verifyRes)
|
||||
(await prover.verify(cancelledProof, inputs)).tryGet == true
|
||||
|
||||
# call asyncVerify and cancel the task
|
||||
let verifyFut = backend.asyncVerify(proof, inputs, verifyRes)
|
||||
let verifyFut = backend.asyncVerify(proof, inputs)
|
||||
verifyFut.cancel()
|
||||
|
||||
var verifyRes: int32
|
||||
try:
|
||||
discard await verifyFut
|
||||
verifyRes = (await verifyFut).tryGet
|
||||
except CatchableError as exc:
|
||||
check exc of CancelledError
|
||||
finally:
|
||||
# validate the verifyResponse
|
||||
check verifyRes[] == true
|
||||
# validate the verifyResponse
|
||||
check verifyRes == ERR_OK
|
||||
|
||||
8
vendor/urls.rules
vendored
8
vendor/urls.rules
vendored
@ -1,8 +0,0 @@
|
||||
https://github.com/status-im/nim-libp2p-dht.git -> https://github.com/codex-storage/nim-codex-dht.git
|
||||
https://github.com/markspanbroek/questionable -> https://github.com/codex-storage/questionable
|
||||
https://github.com/status-im/questionable -> https://github.com/codex-storage/questionable
|
||||
https://github.com/status-im/asynctest -> https://github.com/codex-storage/asynctest
|
||||
https://github.com/status-im/nim-datastore -> https://github.com/codex-storage/nim-datastore
|
||||
https://github.com/cheatfate/nimcrypto -> https://github.com/status-im/nimcrypto
|
||||
protobufserialization -> protobuf_serialization
|
||||
protobufserialization -> https://github.com/status-im/nim-protobuf-serialization
|
||||
Loading…
x
Reference in New Issue
Block a user