zksecurity / noname

Noname: a programming language to write zkapps
https://zksecurity.github.io/noname/
181 stars 47 forks source link

wiring issue #4

Closed mimoo closed 2 years ago

mimoo commented 2 years ago

in example.no we see the following wiring:

cargo run -- --path data/example.no --private-inputs '{"private_input": ["1", "1"]}' --public-inputs '{"public_input": ["3654913405619483358804575553468071097765421484960111776885779739261304758583"]}' --debug

shows that a zero constant is being created via gate number 4 to serve as the capacity of the sponge:

7:     let digest = crypto::poseidon(private_input);
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#4 - DoubleGeneric<1,0,0,0,0>
--------------------------------------------------------------------------------
7:     let digest = crypto::poseidon(private_input);
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#5 - Poseidon<c0,c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14>

and then the private input is wired to the sponge's input:

3: fn main(pub public_input: Field, private_input: [Field; 2]) {
                                    ^^^^^^^^^^^^^
7:     let digest = crypto::poseidon(private_input);
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
(1,0) -> (5,0)
--------------------------------------------------------------------------------
3: fn main(pub public_input: Field, private_input: [Field; 2]) {
                                    ^^^^^^^^^^^^^
7:     let digest = crypto::poseidon(private_input);
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
(1,1) -> (5,1)

this should not happen. There are two issues:

mimoo commented 2 years ago

The first issue seems to be that the private input indeed is used prior to poseidon:

    let x = private_input[0] + private_input[1];
    assert_eq(x, 2);

    let digest = crypto::poseidon(private_input);

so the wiring is correct, but threw me off (it could have displayed the line where private_input is created for the first time, but it would have been confusing for someone who does not know the internals, so I think it is probably fine this way...

For the second issue, the problem was that the wiring of the zero wasn't next to these wiring, but it was there!

7:     let digest = crypto::poseidon(private_input);
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
7:     let digest = crypto::poseidon(private_input);
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
(4,0) -> (5,2)
mimoo commented 2 years ago

I'm glad that there was no bug : ) and that the debugging is such a useful way to dig into the output