arnaucube / go-snark-study

zkSNARK library implementation in Go from scratch (compiler, setup, prover, verifier)
GNU General Public License v3.0
255 stars 57 forks source link

extended parser #8

Closed mottla closed 4 years ago

mottla commented 5 years ago

hello! I've been working on your fork for some time and I think the way I build and traverse the parse tree is quite efficient and handy I reduce all gates that are constant multiplications or additions to minimize the number of gates for a far more efficient proof generation time, and smaler CRS. I have just seen that you started on extending your languages expressability, so I thought I may jump in and take this part, so you can work on smth different

arnaucube commented 5 years ago

Cool! :smiley: Looks good! I can remove the parts that I've been adding last week related to extending circuit compiler in order allow your fork to merge without any conflict. Can you rebase/squash the commits of the PR in order to pack them in a single/less commit for clearer git history? Also, if you can add .idea to .gitignore in order to avoid pushing the editor folder would be great

I'll make a tag of the current version of master branch, and then remove the changes that I've added last week, to allow you to do the pull request to master without any merge conflicts.

mottla commented 5 years ago

Hi! Ok nice lets do this! I'm totaly unexperienced with git, so I apprechiate detailed instructions and I will do my best :) So I rebased all my commits into one big commit. Do I need to make a new pull request now?

The proving part does not work, because I changed your logic a bit. The output is on last index position, whereas you put it right after the inputs. Should I resolve these problem now, or after we merge?

Your manual tests will become oboslete. I've implemented tests in Programm_test. There you can see that witness calculation is now independent from setup phase.

In the next days I'll implement a parser/lexer as rob pike explained in https://www.youtube.com/watch?v=HxaD_trXwRE , and then start working on boolean operation (introduce split gate as in the pinocchio paper)

arnaucube commented 5 years ago

great! ^^ I'll try to make an organized answer:

mottla commented 5 years ago

I started to reposition the output, as you did it before. There are several ways to do this, but I'd prefer to make the lexer more expressive to allow main(arg1,arg2,private arg3, arg4, private arg5) or main(arg1,arg2,arg4,)(arg3, arg5) no other function then main is supposed to allows this syntax.

Anyways I write the lexer soon. I tried a work-around where i reorder r1cs and the witness but then things got messed up. I hang in and try to get things done asap:)

Groth16 should give us quite some speed up! would be nice if we keep both for comparison!

mottla commented 5 years ago

Signal structure is now [1,inputs..,outputs...,trace...] Running the test in snark_test gives: ✓ e(piA, Va) == e(piA', g2), valid knowledge commitment for A ✓ e(Vb, piB) == e(piB', g2), valid knowledge commitment for B ✓ e(piC, Vc) == e(piC', g2), valid knowledge commitment for C ❌ e(Vkx+piA, piB) == e(piH, Vkz) * e(piC, g2), QAP disibility checked I'm not quite sure why, but I think its a simple index problem resulting from the "one" element in the generation phase. Or line 322 in Verify function, where // Vkx, to then calculate Vkx+piA vkxpia := setup.Vk.IC[0] for i := 0; i < len(publicSignals); i++ { vkxpia = Utils.Bn.G1.Add(vkxpia, Utils.Bn.G1.MulScalar(setup.Vk.IC[i], publicSignals[i])) } public signals are [1,inputs,output].

Is the one element the problem?

arnaucube commented 5 years ago

maybe what is happening there is something similar to what was happening in this issue https://github.com/arnaucube/go-snark/issues/1#issuecomment-489463249 ? having as witness: witness = [ one, publicInputs, privateInputs, rest of the signals...]

so there I solved putting an equals(a, b) to the circuit language:

func main(private s0, public s1):
        s2 = s0 * s0
        s3 = s2 * s0
        s4 = s3 + s0
        s5 = s4 + 5
        equals(s1, s5)
        out = 1 * 1

where the equals(s1, s5) is then translated in parsing time to:

s1==s5 * 1
s5==s1 * 1

as is happening in this line: https://github.com/arnaucube/go-snark/blob/master/circuitcompiler/parser.go#L265

Also, I see that you are using inputs and outputs concepts, I didn't had time to completly check that, but what we need there is public inputs and private inputs, in a way that after in the snark proof generation uses the private and public, and in the verification uses the public

If you want, we can chat through some more direct channel that github, in order to discuss better this, I've created this gitter channel were we can have more direct feedback: https://gitter.im/go-snark/community

mottla commented 5 years ago

Ah I had a fundamental missunderstanding! The output of a program is not of our interrest, but rather the correct execution. Now I understand why you made the separation between public and private explicit! The gitter channel is a good idea! I'll be back on thursday! have a good week!

arnaucube commented 5 years ago

exactly :smiley:

teleinfo-bif commented 5 years ago

hello,parser can support calling other functions for example: hash(x) or Encryption function?

arnaucube commented 5 years ago

Hi, Yes, the current version in @master supports importing circuits. This can be done by importing a circuit that is in the same file, and also allows to import a circuit that is in another file. Like in this example https://github.com/arnaucube/go-snark/blob/master/circuitexamples/import-example.circuit imported-example.circuit:

func exp3(private a):
    b = a * a
    c = a * b
    return c

func sum(private a, private b):
    c = a + b
    return c

main-circuit.circuit:

import "imported-example.circuit"

func main(private s0, public s1):
    s3 = exp3(s0)
    s4 = sum(s3, s0)
    s5 = s4 + 5
    equals(s1, s5)
    out = 1 * 1
teleinfo-bif commented 5 years ago

sorry, I may not have made that clear, I mean whether you can call the go language's built-in functions, not your own

` func main(private s0, public s1):
        hash:=crypto.SHA256.New()// this  function is crypto moudle have not myself function
    hash.Write(s0)
    s3=hash.Sum([]byte("1"))
    s4 = sum(s3, s0)
    s5 = s4 + 5
    equals(s1, s5)
    out = 1 * 1`

now this version support int type data,how to support string or byte[] or other type

arnaucube commented 5 years ago

ah ok, no, that's not possible. The circuit file code that then parsed into constraints, and then from that the R1CS are computed, it's not a software program, its a language to provide proofs that the computation has been done in the right way

teleinfo-bif commented 5 years ago

I know, thank you very much