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. While this is quite straightforward in principle, and seems to work on small examples, it turns out that `circom-witnesscalc` itself is completely broken, in the sense that it doesn't seem to be able to handle nontrivial circuits using any kind of meaningful metaprogramming (that being the only thing which makes `circom` borderline useful). And this doesn't look fixable without something like a full rewrite of `circom-witnesscalc` (?). ### Implementation status Compiler (in Haskell): - [x] parsing the graph file - [x] naive interpreter - [ ] constantine backend - [ ] zikkurat backend - [ ] arkworks backend Nim witness generator: - [x] parsing the graph file - [ ] 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 `varint` length - `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...)