This is the code for zkFormer: Verifiable and Private Transformer Inference. This code is built upon libsnark: a C++ library for zkSNARK proofs.
For better understanding of the code structure and functions, the idea of zkSNARKs is briefly introduced. A prover who knows the witness for the NP statement (i.e., a satisfying input/assignment) can produce a short proof attesting to the truth of the NP statement. This proof can be verified by anyone, and offers the following properties.
- Zero knowledge: the verifier learns nothing from the proof beside the truth of the statement (i.e., the value qux, in the above examples, remains secret).
- Succinctness: the proof is short and easy to verify.
- Non-interactivity: the proof is a string (i.e. it does not require back-and-forth interaction between the prover and the verifier).
- Soundness: the proof is computationally sound (i.e., it is infeasible to fake a proof of a false NP statement). Such a proof system is also called an argument.
- Proof of knowledge: the proof attests not just that the NP statement is true, but also that the prover knows why (e.g., knows a valid qux).
We refer to libsnark for more details. Please install libsnark properly.
To test the CRPC and PSQ in zkFormer, please run tests for libsnark/zk_proof_systems/ppzksnark/r1cs_gg_ppzksnark/tests/test_r1cs_gg_ppzksnark_conv.cpp
. To test a matrix multiplication (Figure 7 as well as Table 3), you can specify the shape of the matrix multiplication. Then,under the ./build
directory, you can build and run the test by:
make && make check
To check the runtime, memory usage and breakdown, check the log files in build/Testing/Temporary/LastTest.log
.
The experiments consist of matrix multiplication of different sizes. Specifically, we test the matrix multiplication of libsnark/zk_proof_systems/ppzksnark/r1cs_gg_ppzksnark/tests/test_r1cs_gg_ppzksnark_conv.cpp
, specify the shape the matrix and then run make && make check
. The arguments
- test_r1cs_gg_ppzksnark( ) in
libsnark/zk_proof_systems/ppzksnark/r1cs_gg_ppzksnark/tests/test_r1cs_gg_ppzksnark_conv.cpp
. - generate_r1cs_example_with_matrix( ) in
libsnark/relations/constraint_satisfaction_problems/r1cs/examples/r1cs_examples.tcc
to generate a R1CS example with witness. - The optimization is mudulizaed as a
matrix_gadget
class inlibsnark/gadgetlib3/matrix_gadget.hpp
as well. One can build R1CS instance from the gadgets, as shown inlibsnark/models/r1cs_examples/generate_from_model.hpp
.
The experiments consist of running the matrix multiplication with generate_r1cs_example_with_matrix()
function in libsnark/zk_proof_systems/ppzksnark/r1cs_gg_ppzksnark/tests/test_r1cs_gg_ppzksnark_conv.cpp
. generate_r1cs_example_with_matrix()
for the naive implementattion, generate_r1cs_example_with_matrix_opt
for generate_r1cs_example_with_matrix_opt_4
for
Check the build/Testing/Temporary/LastTest.log
for a detailed runtime breakdown, key sizes as well as memory usage.
The end-to-end runtime is approximated. The component demo code is under libsnark/gadgetlib3
. The runtime is computed by runnning each matrix multiplication in the attention module and MLP layer individually.