The underlying circuit library supports arbitrary number of inputs and outputs, but the top-level circuit must have a fixed size. The fixed size is due to the fact that a ZKP circuit design must not have different steps of computation dependent on the input values. Having variable sized arrays is not possible as a result, because that would cause the circuit runtime to perform different computations dependent on the number of elements in the arrays.
At the moment all top level circuits (in the /zkp/circuits folder) for fungible tokens use 2-sized arrays for both inputs and outputs. Either array can have a 0-valued UTXO so that transactions with either single input or single output can be supported.
With the above, the following combinations of transactions can be supported:
2 inputs, 2 outputs
1 input, 2 outputs (the 2nd element in the inputs array is set to 0)
2 inputs, 1 output (the 2nd element in the outputs array is set to 0)
1 input, 1 output (2nd element in the inputs and outputs array are set to 0)
If we want to support larger sized inputs and outputs, we need the following layers to be updated:
top level circuits, plus the corresponding proving keys, verification keys (optional if verification is only performed by the Solidity verifier code) and the solidity verifier
solidity tokens implementations
Having a larger sized inputs and outputs means that, when not all input elements are used, meaning they are set to 0, all computations are still carried out as if they were non-zero elements, yet the results are not compared with the public inputs. This effectively multiplies the cost of the proof generation, although verification time is still constant thanks to SNARK.
The most efficient way from the runtime point of view is having the exact sized inputs. However this means for every circuit, we need many copies of derived artifacts: verifier contracts, unit tests, etc. Maintenance will be a big headache.
One proposal is having a small number of sizes to cover the majority of the use cases:
2-sized inputs: this probably covers 80% of the cases
10-sized inputs: this is much more expensive to use, in terms of proof generation. this size can be made even larger, since it's only used in rare occasions anyway
The underlying circuit library supports arbitrary number of inputs and outputs, but the top-level circuit must have a fixed size. The fixed size is due to the fact that a ZKP circuit design must not have different steps of computation dependent on the input values. Having variable sized arrays is not possible as a result, because that would cause the circuit runtime to perform different computations dependent on the number of elements in the arrays.
At the moment all top level circuits (in the
/zkp/circuits
folder) for fungible tokens use 2-sized arrays for both inputs and outputs. Either array can have a 0-valued UTXO so that transactions with either single input or single output can be supported.With the above, the following combinations of transactions can be supported:
0
)0
)0
)If we want to support larger sized inputs and outputs, we need the following layers to be updated:
Having a larger sized inputs and outputs means that, when not all input elements are used, meaning they are set to
0
, all computations are still carried out as if they were non-zero elements, yet the results are not compared with the public inputs. This effectively multiplies the cost of the proof generation, although verification time is still constant thanks to SNARK.The most efficient way from the runtime point of view is having the exact sized inputs. However this means for every circuit, we need many copies of derived artifacts: verifier contracts, unit tests, etc. Maintenance will be a big headache.