Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pr add prover cli #817

Open
wants to merge 98 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
98 commits
Select commit Hold shift + click to select a range
0273b78
initial setup
elcritch Apr 23, 2024
74a8a00
reorg
elcritch Apr 23, 2024
e14f065
figuring out basic shell commands
elcritch Apr 23, 2024
f7ed2ac
benchmarks
elcritch Apr 24, 2024
60c9927
benchmarks
elcritch Apr 24, 2024
4146690
Sets up environment for running benchmarks
elcritch Apr 24, 2024
682d03b
updates
elcritch Apr 24, 2024
91c695c
integrate setup and proving
elcritch Apr 24, 2024
5300d4f
updates
elcritch Apr 24, 2024
35a38dd
adding outputs
elcritch Apr 24, 2024
91d4713
cleanup
elcritch Apr 24, 2024
047e8f6
check failure
elcritch Apr 24, 2024
fd6fe2f
benchmarks
elcritch Apr 24, 2024
a2244ec
benchmarks
elcritch Apr 24, 2024
234287d
benchmarks
elcritch Apr 24, 2024
86de771
benchmarks
elcritch Apr 24, 2024
7ba5630
benchmarks
elcritch Apr 24, 2024
e527ebf
benchmarks
elcritch Apr 24, 2024
b43fd95
formatting
elcritch Apr 25, 2024
b548a09
fix running larger sizes
elcritch Apr 29, 2024
2974d23
use larger ceremony file size
elcritch Apr 29, 2024
ae26d6a
use larger ceremony file size
elcritch Apr 29, 2024
5c2f602
use larger ceremony file size
elcritch Apr 29, 2024
b0a3991
restore benchmarks
elcritch Apr 29, 2024
b568b79
Merge branch 'master' into pr-add-prover-benchmark-tool
dryajov Apr 30, 2024
6352392
cleanup
elcritch May 1, 2024
7ed2c0a
cleanup
elcritch May 1, 2024
0c00c7c
cleanup
elcritch May 1, 2024
1204c71
cleanup
elcritch May 1, 2024
fd04b5b
cleanup
elcritch May 1, 2024
b3ca618
cleanup
elcritch May 1, 2024
ccce162
cleanup
elcritch May 1, 2024
0b8e0bd
cleanup
elcritch May 1, 2024
c7e0b48
cleanup
elcritch May 1, 2024
5ee0210
cleanup
elcritch May 1, 2024
9b87b81
refactor env
elcritch May 2, 2024
b118792
refactor env
elcritch May 2, 2024
4aa45da
refactor env
elcritch May 2, 2024
f609151
refactor env
elcritch May 2, 2024
90db9ef
refactor env
elcritch May 2, 2024
e07c767
rename
elcritch May 2, 2024
6da023a
cleanup
elcritch May 2, 2024
e969e22
cleanup
elcritch May 2, 2024
7c764d0
cleanup
elcritch May 2, 2024
d9ee7c0
cleanup
elcritch May 2, 2024
be0527f
cleanup
elcritch May 2, 2024
c3a69cc
cleanup
elcritch May 2, 2024
3603e78
readme
elcritch May 2, 2024
047c026
readme
elcritch May 2, 2024
0d4c06d
Merge branch 'pr-add-prover-benchmark-tool' of github.com:codex-stora…
elcritch May 2, 2024
bb09577
merge
elcritch May 2, 2024
3a86155
initial splitout of codex ark prover cli
elcritch May 2, 2024
0d6fcb3
opts
elcritch May 2, 2024
1d3b948
copying nimcli opts
elcritch May 2, 2024
cf1c67e
copying nimcli opts
elcritch May 2, 2024
741d448
copying nimcli opts
elcritch May 2, 2024
cfd8059
updating ark cli
elcritch May 2, 2024
8f7aec5
updating ark cli
elcritch May 2, 2024
fe268a4
updating ark cli
elcritch May 2, 2024
d6863e9
updating ark cli
elcritch May 2, 2024
b842f76
updating ark cli
elcritch May 2, 2024
f2d41da
updating ark cli
elcritch May 2, 2024
2e9a638
updating ark cli
elcritch May 2, 2024
f1732d5
updating ark cli
elcritch May 2, 2024
6a6f3ff
docs
elcritch May 2, 2024
c09c476
Merge branch 'master' into pr-add-prover-benchmark-tool
dryajov May 6, 2024
ae9711a
Merge branch 'master' into pr-add-prover-benchmark-tool
elcritch May 9, 2024
458ef7d
update
elcritch May 10, 2024
e39b5ef
import circom helpers
elcritch May 10, 2024
018be61
import circom helpers
elcritch May 10, 2024
2b82c4a
cleanup
elcritch May 11, 2024
0c23b42
rename
elcritch May 23, 2024
39a1493
rename
elcritch May 23, 2024
cbd59da
rename
elcritch May 23, 2024
0d26410
fixes
elcritch May 24, 2024
2c26b0a
fixes
elcritch May 24, 2024
c5225c8
comments
elcritch May 24, 2024
42e9438
updates
elcritch May 24, 2024
7db7db3
updates
elcritch May 24, 2024
1c6d877
Merge remote-tracking branch 'origin/master' into pr-add-prover-cli
elcritch May 24, 2024
8ed0911
updates
elcritch May 27, 2024
2fea35c
proving
elcritch May 28, 2024
472fbef
proving wiring
elcritch May 28, 2024
6afbdfe
adding proof input outputs
elcritch May 28, 2024
efee6bf
adding proof input outputs
elcritch May 28, 2024
4fdddaf
adding proof input outputs
elcritch May 28, 2024
50d3ab8
adding verification
elcritch May 28, 2024
ae01d06
adding verification
elcritch May 28, 2024
ace2379
adding verification
elcritch May 28, 2024
cee3340
adding verification
elcritch May 28, 2024
6b3e3d2
adding verification
elcritch May 28, 2024
85f7c6b
adding verification
elcritch May 28, 2024
47018f3
adding verification
elcritch May 28, 2024
3184638
adding verification
elcritch May 28, 2024
c962462
reformat verification
elcritch May 28, 2024
8b831c6
example for cli
elcritch May 29, 2024
142c27e
cleanup cli
elcritch May 29, 2024
75403f8
cleanup cli
elcritch May 29, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
284 changes: 284 additions & 0 deletions benchmarks/circomcompat_cli.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,284 @@
import std/[sequtils, strformat, os, options, importutils]
import std/[times, os, strutils, terminal, parseopt, json, sets]

import pkg/questionable
import pkg/questionable/results
import pkg/serde/json except `%*`, `%`

import pkg/circomcompat
import pkg/poseidon2/io

import ./utils
import ./create_circuits
import ./clitypes

type CircomCircuit* = object
r1csPath*: string
wasmPath*: string
zkeyPath*: string
inputsPath*: string
dir*: string
circName*: string
backendCfg: ptr CircomBn254Cfg
vkp*: ptr VerifyingKey
cmds*: HashSet[string]

proc release*(self: CircomCircuit) =
## Release the ctx
##
if not isNil(self.backendCfg):
self.backendCfg.unsafeAddr.releaseCfg()
if not isNil(self.vkp):
self.vkp.unsafeAddr.release_key()

proc initialize*(self: var CircomCircuit) =
## Create a new ctx
##

var cfg: ptr CircomBn254Cfg
var zkey = if self.zkeyPath.len > 0: self.zkeyPath.cstring else: nil

if initCircomConfig(
self.r1csPath.cstring, self.wasmPath.cstring, self.zkeyPath.cstring, cfg.addr
) != ERR_OK or cfg == nil:
if cfg != nil:
cfg.addr.releaseCfg()
raiseAssert("failed to initialize circom compat config")

var vkpPtr: ptr VerifyingKey = nil

if cfg.getVerifyingKey(vkpPtr.addr) != ERR_OK or vkpPtr == nil:
if vkpPtr != nil:
vkpPtr.addr.releaseKey()
raiseAssert("Failed to get verifying key")

self.backendCfg = cfg
self.vkp = vkpPtr

proc parseJsons(
ctx: var ptr CircomCompatCtx,
key: string,
value: JsonNode
) =
if value.kind == JString:
var num = value.parseBigInt()
# echo "Big NUM: ", num
if (let res = ctx.pushInputU256Array(key.cstring, num.addr, 1); res != ERR_OK):
raise newException(ValueError, "Failed to push BigInt from dec string " & $res)
elif value.kind == JInt:
var num = value.getInt().uint32
# echo "NUM: ", num, " orig: ", value.getInt()
if ctx.pushInputU32(key.cstring, num) != ERR_OK:
raise newException(ValueError, "Failed to push JInt")
elif value.kind == JArray:
var inputs = newSeq[UInt256]()
for item in value:
if item.kind == JString:
doAssert item.kind == JString
inputs.add item.parseBigInt()
elif item.kind == JArray:
for subitem in item:
doAssert subitem.kind == JString
inputs.add subitem.parseBigInt()
if (let res = ctx.pushInputU256Array(key.cstring, inputs[0].addr, inputs.len.uint); res != ERR_OK):
raise newException(ValueError, "Failed to push BigInt from dec string " & $res)
else:
echo "unhandled val: " & $value
raise newException(ValueError, "Failed to push Json of " & $value.kind)

proc initCircomCtx*(
self: CircomCircuit, input: JsonNode
): ptr CircomCompatCtx =
# TODO: All parameters should match circom's static parametter
var ctx: ptr CircomCompatCtx

if initCircomCompat(self.backendCfg, addr ctx) != ERR_OK or ctx == nil:
raiseAssert("failed to initialize CircomCircuit ctx")

for key, value in input:
# echo "KEY: ", key, " VAL: ", value.kind
ctx.parseJsons(key, value)

return ctx

proc prove*(
self: CircomCircuit, ctx: ptr CircomCompatCtx
): CircomProof =
## Encode buffers using a ctx
##

var proofPtr: ptr Proof = nil

let proof: Proof =
try:
if (let res = self.backendCfg.proveCircuit(ctx, proofPtr.addr); res != ERR_OK) or
proofPtr == nil:
echo "Failed to prove - err code: " & $res

proofPtr[]
finally:
if proofPtr != nil:
proofPtr.addr.releaseProof()

# echo "Proof:"
# echo proof
# echo "\nProof:json: "
let g16proof: Groth16Proof = proof.toGroth16Proof()
let proofStr = pretty(%*(g16proof))
writeFile(self.dir / "proof.json", proofStr)
return proof

proc verify*(
self: CircomCircuit,
inputs: ptr Inputs,
proof: CircomProof,
): bool =
## Verify a proof using a ctx

echo "inputs val: ", inputs.repr

let res = verifyCircuit(proof.unsafeAddr, inputs, self.vkp)

if res == ERR_OK:
result = true
elif res == ERR_FAILED_TO_VERIFY_PROOF:
result = false
else:
raise newException(ValueError, "Failed to verify proof - err code: " & $res)

echo "proof verification result: ", result


proc printHelp() =
echo "usage:"
echo " ./circom_ark_prover_cli [options] "
echo ""
echo "available options:"
echo " -h, --help : print this help"
echo " -v, --verbose : verbose output (print the actual parameters)"
echo " --r1cs:$FILE : r1cs file path"
echo " --wasm:$FILE : wasm file path"
echo " --zkey:$FILE : zkey file path"
echo " --inputs:$FILE : inputs.json file path"
echo ""
echo "Must provide files options. Use either:"
echo " --dir:$CIRCUIT_DIR --name:$CIRCUIT_NAME"
echo "or:"
echo " --r1cs:$R1CS --wasm:$WASM --zkey:$ZKEY"
echo ""

quit(1)

proc parseCliOptions(self: var CircomCircuit) =
var argCtr: int = 0
template expectPath(val: string): string =
if val == "":
echo "ERROR: expected path a but got empty for: ", key
printHelp()
val.absolutePath

# for kind, key, value in getOpt(params):
for kind, key, value in getOpt():
case kind

# Positional arguments
of cmdArgument:
if key in ["prove", "verify"]:
self.cmds.incl key
else:
echo "\nERROR: got unexpected arg: ", key, "\n"
printHelp()

# Switches
of cmdLongOption, cmdShortOption:
case key
of "h", "help":
printHelp()
of "r1cs":
self.r1csPath = value.expectPath()
of "wasm":
self.wasmPath = value.expectPath()
of "zkey":
self.zkeyPath = value.expectPath()
of "inputs":
self.inputsPath = value.expectPath()
of "dir":
self.dir = value.expectPath()
of "name":
self.circName = value
else:
echo "Unknown option: ", key
echo "use --help to get a list of options"
quit()
of cmdEnd:
discard

proc run*() =
## Run Codex Ark/Circom based prover
##
echo "Running prover"

# prove wasm ${CIRCUIT_MAIN}.zkey witness.wtns proof.json public.json

var self = CircomCircuit()

parseCliOptions(self)

let dir =
if self.dir != "":
self.dir
else:
getCurrentDir()
if self.circName != "":
if self.r1csPath == "":
self.r1csPath = dir / fmt"{self.circName}.r1cs"
if self.wasmPath == "":
self.wasmPath = dir / fmt"{self.circName}.wasm"
if self.zkeyPath == "":
self.zkeyPath = dir / fmt"{self.circName}.zkey"

if self.inputsPath == "":
self.inputsPath = dir / fmt"inputs.json"

echo "Got file args: ", self

var fileErrors = false
template checkFile(file, name: untyped) =
if file == "" or not file.fileExists():
echo "\nERROR: must provide `" & name & "` file"
fileErrors = true

checkFile self.inputsPath, "input json"
checkFile self.r1csPath, "r1cs"
checkFile self.wasmPath, "wasm"
checkFile self.zkeyPath, "zkey"

if fileErrors:
echo "ERROR: couldn't find all files"
printHelp()

self.initialize()

var
inputData = self.inputsPath.readFile()
inputs: JsonNode = !JsonNode.parse(inputData)

var ctx = initCircomCtx(self, inputs)
defer:
if ctx != nil:
ctx.addr.releaseCircomCompat()

if "prove" in self.cmds or "verify" in self.cmds:
let proof = prove(self, ctx)

var pubInputs: ptr Inputs
defer:
if pubInputs != nil:
release_inputs(pubInputs.addr)
doAssert ctx.get_pub_inputs(pubInputs.addr) == ERR_OK

if "verify" in self.cmds:
let verified = verify(self, pubInputs, proof)

when isMainModule:
run()
58 changes: 58 additions & 0 deletions benchmarks/clitypes.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import pkg/stint
import pkg/circomcompat
# import pkg/serde/json
import std/json

export stint, json

type
CircomG1* = G1
CircomG2* = G2

CircomProof* = Proof
CircomKey* = VerifyingKey
CircomInputs* = Inputs

type
Groth16Proof* = object
a*: G1Point
b*: G2Point
c*: G1Point
G1Point* = object
x*: UInt256
y*: UInt256
# A field element F_{p^2} encoded as `real + i * imag`
Fp2Element* = object
real*: UInt256
imag*: UInt256
G2Point* = object
x*: Fp2Element
y*: Fp2Element

func `%`*(integer: UInt256): JsonNode =
%($(integer))

func toG1*(g: CircomG1): G1Point =
G1Point(
x: UInt256.fromBytesLE(g.x),
y: UInt256.fromBytesLE(g.y))

func toG2*(g: CircomG2): G2Point =
G2Point(
x: Fp2Element(
real: UInt256.fromBytesLE(g.x[0]),
imag: UInt256.fromBytesLE(g.x[1])
),
y: Fp2Element(
real: UInt256.fromBytesLE(g.y[0]),
imag: UInt256.fromBytesLE(g.y[1])
))

func toGroth16Proof*(proof: CircomProof): Groth16Proof =
Groth16Proof(
a: proof.a.toG1,
b: proof.b.toG2,
c: proof.c.toG1)

proc parseBigInt*(input: JsonNode): UInt256 =
parse( input.str, UInt256 )
Loading
Loading