NilFoundation / zkLLVM

Zero-Knowledge Proof Systems Circuit Compiler
https://docs.nil.foundation/zkllvm
274 stars 46 forks source link

Verification of proof fails on eq CPP example #558

Closed akokoshn closed 4 months ago

akokoshn commented 4 months ago

Comes from LIDO integration.

Code:

#include <nil/crypto3/hash/algorithm/hash.hpp>
#include <nil/crypto3/hash/sha2.hpp>
#include <cstdint>

using namespace nil::crypto3;

bool is_same(typename hashes::sha2<256>::block_type block0,
    typename hashes::sha2<256>::block_type block1){

    return block0[0] == block1[0] && block0[1] == block1[1];
}

constexpr size_t SIZE = 1;

[[circuit]] void conditional_sum_and_count(
    [[private_input]] std::array<hashes::sha2<256>::block_type, SIZE> credentials,
    [[private_input]] std::array<hashes::sha2<256>::block_type, SIZE> credentials1
) {
    bool test =is_same(credentials[0], credentials1[0]);
}

Input:

[
    {
            "array": [
                {"vector": [
                    {"field": "166209954665300884822717121800188038799"},
                    {"field": "144783094885247872016525034474730739405"}
                ]}
            ]
        },
    {
            "array": [
                {"vector": [
                    {"field": "166209954665300884822717121800188038799"},
                    {"field": "144783094885247872016525034474730739405"}
                ]}
            ]
        }
]

Failed cmd:

cd /root/zkLLVM/build/examples/cpp && /root/zkLLVM/build/bin/transpiler/transpiler -m gen-test-proof -i /root/zkLLVM/examples/inputs/compare/eq.inp -c circuit_compare_eq_cpp.crct -t assignment_compare_eq_cpp.tbl -o transpiler_output_compare_eq_cpp -e pallas 
akokoshn commented 4 months ago

Not reproduced on the zkLLVM master.

assigner -b is_same.cpp.ll -p is_same.inp -c circuit.crct -t assignment.tbl  -e pallas
transpiler -m gen-test-proof -i is_same.inp -c circuit.crct -t assignment.tbl -o transpiler_output -e pallas --optimize-gates
akokoshn commented 4 months ago

assignment.tbl.txt circuit.crct.txt is_same.cpp.ll.txt

0xAleksaOpacic commented 4 months ago

Hey @akokoshn. Thank you for providing the files and i can confirm that using these, assigner and transpiler works:

root@ubuntu-aleksaopacic-devserver:~/zkLLVM# assigner -b is_same.cpp.ll -p /root/zkLLVM/examples/inputs/compare/eq_private.inp -c circuit.crct -t assignment.tbl  -e pallas
root@ubuntu-aleksaopacic-devserver:~/zkLLVM# transpiler -m gen-test-proof -i /root/zkLLVM/examples/inputs/compare/eq_private.inp -c circuit.crct -t assignment.tbl -o transpiler_output -e pallas --optimize-gates
Directory Created: transpiler_output
Preprocessing public data...
Preprocessing private data...
Generating proof...
Proof generated
Verifying proof...
Proof is verified
Writing proof to transpiler_output/proof.bin...
Proof written

Also i tested doing all of this in the zkllvm_template where i copied cpp and input in source and follow guide: https://github.com/NilFoundation/zkllvm-template?tab=readme-ov-file#steps-1-3-let-script-perform-steps-1-3 and again i was able to generate proof (attached log file-zkllvm.txt): zkllvm.txt

But, where the issue exists is when i try to generate contracts ready for blockchain deployment and verification. I want to do this so i can copy paste the generated folder in evm-placeholder-verification. I do this using these 2 commands:

cmake -G "Ninja" -B ${ZKLLVM_BUILD:-build} -DCMAKE_BUILD_TYPE=Release -DCIRCUIT_ASSEMBLY_OUTPUT=TRUE -DBUILD_TESTS=True -DGENERATE_EVM_VERIFIER=TRUE .
ninja -C build compare_eq_cpp_evm_verifier

As you can see i am building cpp_evm_verifier and that -DGENERATE_EVM_VERIFIER=TRUE

How did i test it:

  1. I changed the code for examples/cpp/compare/eq.cpp to match the one linked in the issue
  2. I added _private input by adding new file in the examples/inputs/compare/eq_private.inp and i also changed examples/inputs/compare/eq.inp to [] as we do not have public inputs
  3. Configured the project using: cmake -G "Ninja" -B ${ZKLLVM_BUILD:-build} -DCMAKE_BUILD_TYPE=Release -DCIRCUIT_ASSEMBLY_OUTPUT=TRUE -DBUILD_TESTS=True -DGENERATE_EVM_VERIFIER=TRUE .
  4. Build for evm_verifier: ninja -C build compare_eq_cpp_evm_verifier -v

    Versions

    /root/zkLLVM/build/bin/transpiler/transpiler - 0.1.17-10 /root/zkLLVM/build/bin/assigner/assigner - 0.1.17-10 /root/zkLLVM/build/libs/circifier/llvm/bin/llvm-link - 17.0.4 /root/zkLLVM/build/libs/circifier/llvm/bin/clang-17 - 17.0.4

    Logs

    conf.txt build.txt

GitHub Commit

d2d89c22cd79af51fe029c83560a927909e12b84

If you need anything else, please feel free to ask, happy to provide 🚀 Thank you so much for taking time to look at this issue 🙏

0xAleksaOpacic commented 4 months ago

Update

I've updated to latest master branch (ccbdf0149986681b4fa7976cc012814a2feef135), and re-done the tests. I have a new issue now:

FAILED: examples/cpp/CMakeFiles/compare_eq_cpp_prepare_input /root/zkLLVM/build/examples/cpp/CMakeFiles/compare_eq_cpp_prepare_input 
cd /root/zkLLVM/build/examples/cpp && /root/zkLLVM/build/bin/assigner/assigner -b compare_eq_cpp.ll -i /root/zkLLVM/examples/inputs/compare/eq.inp --generate-type public-input-column --input-column compare_eq_cpp_input_column.inp -e pallas

Public input does not match the circuit signature: too many values in the input files, public + private input sizes must be equal to function.arg_size - ret_gap

[19/22] cd /root/zkLLVM/build/examples/cpp && /root/zkLLVM/build/bin/assigner/assigner -b compare_eq_cpp.ll -c circuit_compare_eq_cpp.crct -e pallas --generate-type circuit 0

I assume that the command is not taking private inputs. Will debug it and update you on what i found

0xAleksaOpacic commented 4 months ago

Update

I would say that this new issue is related to this line added in latest commit https://github.com/NilFoundation/zkLLVM/commit/ccbdf0149986681b4fa7976cc012814a2feef135#diff-940e5356fa1137e646ea135a6f68cacbfad4fe7124c3a69163468f588acf9283R62. Does not have enough knowledge in this part of the codebase to debug it fully

akokoshn commented 4 months ago
  1. Fails because was changed eq.cpp input from public to private, need to modify cmake. Now we not support only private input. For the local test can be used public input, or apply modification (not tested for all examples) - 0001-Pure-private-input-or-eq-example.patch.txt
  2. Found real issue: assigner produce different circuit.crct in generate type 'circuit' and circuit-assignment - fix in progress
0xAleksaOpacic commented 4 months ago

Hey @akokoshn, thank you looking into these issues!

I am not sure i understand the fix for 1th one. I tried keeping only public inputs and removing private: eq.cpp

#include <nil/crypto3/hash/algorithm/hash.hpp>
#include <nil/crypto3/hash/sha2.hpp>
#include <cstdint>

using namespace nil::crypto3;

bool is_same(typename hashes::sha2<256>::block_type block0,
    typename hashes::sha2<256>::block_type block1){

    return block0[0] == block1[0];
}

constexpr size_t SIZE = 1;

[[circuit]] void conditional_sum_and_count(
    std::array<hashes::sha2<256>::block_type, SIZE> credentials,
    std::array<hashes::sha2<256>::block_type, SIZE> credentials1
) {
    bool test =is_same(credentials[0], credentials1[0]);
}

eq.inp

[
    {
            "array": [
                {"vector": [
                    {"field": "166209954665300884822717121800188038799"},
                    {"field": "144783094885247872016525034474730739405"}
                ]}
            ]
    },
    {
            "array": [
                {"vector": [
                    {"field": "166209954665300884822717121800188038799"},
                    {"field": "144783094885247872016525034474730739405"}
                ]}
            ]
        }
]

And i removed private input completely, the file and from the cMakeList: add_example_with_proving(compare_eq_cpp SOURCES compare/eq.cpp INPUT compare/eq.inp CURVE_TYPE pallas)

and i still have an error:

[4019/4022] cd /root/zkLLVM/build/examples/cpp && /root/zkLLVM/build/bin/assigner/assigner -b compare_eq_cpp.ll -c circuit_compare_eq_cpp.crct -e pallas --generate-type circuit 0
[4020/4022] cd /root/zkLLVM/build/examples/cpp && /usr/bin/cmake -E make_directory transpiler_output_compare_eq_cpp && /usr/bin/cmake -E copy compare_eq_cpp_input_column.inp transpiler_output_compare_eq_cpp/public_input.inp
[4021/4022] cd /root/zkLLVM/build/examples/cpp && /root/zkLLVM/build/bin/transpiler/transpiler -m gen-test-proof -c circuit_compare_eq_cpp.crct -t assignment_compare_eq_cpp.tbl -o transpiler_output_compare_eq_cpp -e pallas
FAILED: examples/cpp/CMakeFiles/compare_eq_cpp_prove /root/zkLLVM/build/examples/cpp/CMakeFiles/compare_eq_cpp_prove 
cd /root/zkLLVM/build/examples/cpp && /root/zkLLVM/build/bin/transpiler/transpiler -m gen-test-proof -c circuit_compare_eq_cpp.crct -t assignment_compare_eq_cpp.tbl -o transpiler_output_compare_eq_cpp -e pallas
Preprocessing public data...
Preprocessing private data...
Generating proof...
Proof generated
Verifying proof...
Assertion failed at /root/zkLLVM/bin/transpiler/src/main.cpp:529:
        verification_result -> Proof is not verified
Aborted (core dumped)

When i did:

cmake -G "Ninja" -B ${ZKLLVM_BUILD:-build} -DCMAKE_BUILD_TYPE=Release -DCIRCUIT_ASSEMBLY_OUTPUT=TRUE -DBUILD_TESTS=True -DGENERATE_EVM_VERIFIER=TRUE .

and

ninja -C build compare_eq_cpp_evm_verifier -v 
0xAleksaOpacic commented 4 months ago

Update

Cherry picking this commit https://github.com/NilFoundation/zkllvm-assigner/commit/553eac7884f2cf0499135a82938dc1cfb37a0439 fixed first issue