Nim: parse the circuit input JSON files

This commit is contained in:
Balazs Komuves 2025-03-15 13:53:42 +01:00
parent 28b368d92a
commit ec327944e2
No known key found for this signature in database
GPG Key ID: F63B7AEF18435562
3 changed files with 62 additions and 15 deletions

View File

@ -3,8 +3,8 @@ Circom witness generators
-------------------------
The original idea behind this small project was to take the "computation graph"
files generated by [`circom-witnesscalc`](https://github.com/iden3/circom-witnesscalc),
and either interprets or compiles them to various algebra backends.
files generated by [`circom-witnesscalc`](https://github.com/iden3/circom-witnesscalc),
and either interpret or compile them to various algebra backends.
While this is quite straightforward in principle, and seems to work on particular
examples, it turns out that `circom-witnesscalc` itself has some serious limitations.
@ -30,8 +30,9 @@ Compiler (in Haskell):
Nim witness generator (to be used with [`nim-groth16`](https://github.com/codex-storage/nim-groth16))
- [x] parsing the graph file
- [ ] parsing json input
- [x] parsing json input
- [ ] generating the witness
- [ ] exporting the witness
- [ ] proper error handling
### Testing & correctness
@ -50,18 +51,18 @@ by `circom-witnesscalc`.
This has the following format:
- magic header: "wtns.graph.001" (14 bytes)
- magic header: `"wtns.graph.001"` (14 bytes)
- number of nodes (8 bytes little endian)
- list of nodes, in protobuf serialized format. Each prefixed by a `varint` length
- `GraphMetaData`, in protobuf
- 8 bytes offset (yes, _at the very end_...), pointing to the start of `GraphMetaData`
- list of nodes, in protobuf serialized format. Each one is prefixed by a `varint` length
- after that, `GraphMetaData`, encoded with protobuf
- finally, 8 bytes little-endian offset (yes, _at the very end_...), pointing to the start of `GraphMetaData`
Node format:
- varint length prefix
- protobuf tag-byte (lower 3 bits are `0x02`, upper bits are node type 1..5)
- protobuf tag-byte (lower 3 bits are `0x02`, upper bits are node type `1..5`)
- varint length
- several record fields
- protobuf tag-byte (lower 3 bits are 0x00, upper bits are field index 1,2,3,4)
- value is varint word32, except for ConstantNode when it's a little-endian bytes
(wrapped a few times, because protobuf is being protobuf...)
- protobuf tag-byte (lower 3 bits are `0x00`, upper bits are field index `1,2,3,4`)
- value is varint word32, except for `ConstantNode` when it's a sequence of little-endian bytes,
encoding a field element (wrapped a few times, because protobuf is being protobuf...)

View File

@ -0,0 +1,39 @@
import std/sequtils
import std/json
import std/tables
import ./field
#-------------------------------------------------------------------------------
type
Inputs* = Table[string, seq[F]]
proc printInputs*(inputs: Inputs) =
for key, list in pairs(inputs):
echo key
for y in list:
echo " - " & fToDecimal(y)
proc flattenNode(node: JsonNode): seq[F] =
case node.kind:
of JString: return @[decimalToF(node.str)]
of JInt: return @[int64ToF(node.num)]
of JArray: return node.elems.map(flattenNode).concat()
else: assert( false, "parseInputJSON: expecting a number or a list (of numbers)" )
proc parseInputJSON*(json: JsonNode): Inputs =
doAssert json.kind == JObject
var stuff: Inputs
for key, node in pairs(json.fields):
stuff[key] = flattenNode(node)
return stuff
proc loadInputJSON*(fpath: string): Inputs =
let text = readFile(fpath)
let json = parseJson(text)
return parseInputJSON(json)
#-------------------------------------------------------------------------------

View File

@ -1,9 +1,16 @@
import circom_witnessgen/graph
import circom_witnessgen/load
import circom_witnessgen/input_json
const graph_file: string = "../tmp/graph4.bin"
const input_file: string = "../tmp/input4.json"
when isMainModule:
let fn = "/Users/bkomuves/zk/codex/circom-witnessgen-compiler/tmp/graph2.bin"
echo "loading in " & fn
let g = loadGraph(fn)
echo $g
echo "\nloading in " & input_file
let inp = loadInputJSON(input_file)
printInputs(inp)
echo "\nloading in " & graph_file
let gr = loadGraph(graph_file)
# echo $gr