2025-03-13 17:55:37 +01:00
|
|
|
|
|
|
|
|
Circom witness generators
|
|
|
|
|
-------------------------
|
|
|
|
|
|
2025-03-14 12:29:39 +01:00
|
|
|
The original idea behind this small project was to take the "computation graph"
|
|
|
|
|
files generated by [`circom-witnesscalc`](https://github.com/iden3/circom-witnesscalc),
|
2025-03-13 17:55:37 +01:00
|
|
|
and either interprets or compiles them to various algebra backends.
|
|
|
|
|
|
2025-03-14 12:29:39 +01:00
|
|
|
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` (?).
|
|
|
|
|
|
2025-03-13 17:55:37 +01:00
|
|
|
### Implementation status
|
|
|
|
|
|
|
|
|
|
Compiler (in Haskell):
|
|
|
|
|
|
2025-03-14 12:29:39 +01:00
|
|
|
- [x] parsing the graph file
|
2025-03-13 17:55:37 +01:00
|
|
|
- [x] naive interpreter
|
|
|
|
|
- [ ] constantine backend
|
|
|
|
|
- [ ] zikkurat backend
|
|
|
|
|
- [ ] arkworks backend
|
|
|
|
|
|
|
|
|
|
Nim witness generator:
|
|
|
|
|
|
2025-03-14 12:29:39 +01:00
|
|
|
- [x] parsing the graph file
|
2025-03-13 17:55:37 +01:00
|
|
|
- [ ] 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...)
|