Circom witness generators
The original idea behind this small project was to take the "computation graph"
files generated by circom-witnesscalc,
and either interprets or compiles 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.
The biggest one is that it doesn't support any kind of dynamic computation (which should be obvious from the fact that it produces a static graph). But even if one uses only static computations, there are further very annoying things which just don't work.
However at the end this is still a useful thing.
Implementation status
Compiler (in Haskell):
- parsing the graph file
- parsing json input
- naive interpreter
- exporting the witness
- constantine backend
- zikkurat backend
- arkworks backend
Nim witness generator (to be used with nim-groth16)
- parsing the graph file
- parsing json input
- generating the witness
- proper error handling
Testing & correctness
I haven't yet done any proper testing, apart from "works for our purposes".
Circuit optimizations
NOTE: you have to run circom with the --O2 options, otherwise the
witness format will be most probably incompatible with the the one generated
by circom-witnesscalc.
Graph file format
circom-witnesscalc produces binary files encoding a computation graph.
This has the following format:
- 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
varintlength GraphMetaData, in protobuf- 8 bytes 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) - 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...)