Coder Social home page Coder Social logo

zokrates / zokrates Goto Github PK

View Code? Open in Web Editor NEW
1.8K 42.0 353.0 18.5 MB

A toolbox for zkSNARKs on Ethereum

Home Page: https://zokrates.github.io

License: GNU Lesser General Public License v3.0

Rust 93.43% Dockerfile 0.04% Shell 0.65% JavaScript 0.78% SMT 5.06% HTML 0.05%
zksnarks ethereum zero-knowledge snark language verifiable-computation

zokrates's Introduction

ZoKrates

Join the chat at https://gitter.im/ZoKrates/Lobby CircleCI develop

ZoKrates is a toolbox for zkSNARKs on Ethereum.

This is a proof-of-concept implementation. It has not been tested for production.

Getting Started

Load the ZoKrates Plugin on Remix to write your first SNARK program!

Alternatively, you can install the ZoKrates CLI:

curl -LSfs get.zokrat.es | sh

Have a look at the documentation for more information about using ZoKrates. Get started, then try a tutorial!

Getting Help

If you run into problems, ZoKrates has a Gitter room.

License

ZoKrates is released under the GNU Lesser General Public License v3.

Contributing

We happily welcome contributions. You can either pick an existing issue or reach out on Gitter.

Unless you explicitly state otherwise, any contribution you intentionally submit for inclusion in the work shall be licensed as above, without any additional terms or conditions.

Git Hooks

You can enable zokrates git hooks locally by running:

git config core.hooksPath .githooks

{js,json,ts} formatting

We enforce strict formatting of .{js,json,ts} files in CI. This check is not included in the git hooks. If you modify such a file, you can ensure its formatting is correct by running:

npm i -g prettier
prettier --write "./**/*.{js,ts,json}" --ignore-path .gitignore

zokrates's People

Contributors

3psil0n avatar alexeizamyatin avatar axic avatar brianguo avatar cosmoviola avatar dark64 avatar edisinovcic avatar erikp0 avatar eupn avatar fleupold avatar fulldecent avatar gballet avatar jacobeberhardt avatar johnnydotdev avatar kyroy avatar leonardoalt avatar lovesh avatar lubieplacki avatar m1cm1c avatar musalbas avatar nirvantyagi avatar petscheit avatar qbzzt avatar rex4539 avatar sanchopansa avatar schaeff avatar stefandeml avatar steffen93 avatar tjade273 avatar turupawn avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

zokrates's Issues

Verifiying a SHA256

Hey @JacobEberhardt awesome work,
I look forward to see this being used and reached production level.

  • I was wondering how would I go about proving knowing the pre-image of a sha256?
  • Should I re-implement sha256 in.. .code?
  • Is it possible to have it as "gadget" and have a much simpler language than directly using C in libsnark?

Project: Bringing (libsnark) gadgets to ZoKrates

Hello everyone,
I finally wrapped my head around what is needed to make #2 happen :)

Current state: ZoKrates is really great - however, as soon as more complex primitives (SHA #2 and others) are required for designing a circuit, you either end up using libsnark or you will have to reimplement those carefully designed gadgets from libsnark again in ZoKrates (really prone to errors!)

There is hope: What if we could export gadgets from libsnark into R1CS that can be imported into ZoKrates? Then ZoKrates would be a really simple glue to combine gadgets and make circuts that Libsnark can then use. Once we have the ability of re-using circuits, then ZoKrates can really reach a wider audience which is not just "prototyping".

Note: This might even be a project where ZoKrates as a community could apply for grants (Zec? Protocol Labs? Eth?)

Ack: So talking to @JacobEberhardt @lgarron, I assembled this list of tasks/projects that we as a community should look into to make the leap with ZoKrates


Project: Gadgets to ZoKrates

  • Aim: This project is to make it easy for developers to write and debug SNARK circuits.
  • Conjecture: If the complexity of writing SNARKs is abstracted away by libraries such as libsnark, then what's left is the writing (and optimizing) of circuits. If can have gadgets and a high level language to combine gadgets, then it is easy to write and debug SNARK circuits.

Objectives

There are three objectives, and they can be run in parallel:

  • Objective 1: Get R1CS gadgets from libsnark
    • Use amiller's code from zcash to extract circuits from libsnark
    • flatten all the gadgets
  • Objective 2: Make libsnark use R1CS(=flattened ZoK) as input
  • Objective 3: Make ZoKrates use gadgets
    • add multireturn #18
    • improved flattening
    • add import statements (*)

/cc @amiller, @JacobEberhardt, @barryWhiteHat, @Schaeff

Possible Less-Than Operator Issue?

Hello,

I've been playing with this toolbox for a few days and am attempting some somewhat complex code, but I have ran into some strange behavior when using the the less-than operator.

The issue doesn't arise when the code is simple. An example starting point:

def lt(a,b):
    return if a < b then 1 else 0 fi

def main():
    return lt(31337, 2197)

As expected, the returned value when main() is called is 0.

A minor note (mostly for my own sanity): we can make a slight adjustment and get the same result:

def lt(a,b):
    return if a < b then 1 else 0 fi

def cutoff():
    return 31337

def main():
    return lt(cutoff(), 2197)

Now, let's introduce some slight complexity, allowing 31337 to be compared to another valueโ€”a value that is computationally arrived upon based off of an input:

def getThing(index):
    result = 3
    result = if index == 0 then 13 else result fi
    result = if index == 1 then 23 else result fi
    result = if index == 2 then 43 else result fi
    result = if index == 3 then 53 else result fi
    result = if index == 4 then 73 else result fi
    result = if index == 5 then 83 else result fi
    return result

def cubeThing(thing):
    return thing**3

def main(index):
    thing = getThing(index)
    thing = cubeThing(thing)
    return thing

We can call our new main() function with an argument of 0, and the returned value is 2197. So far so good.

Things seem to go awry when we try to combine our new stuff with the old stuff:

def lt(a,b):
    return if a < b then 1 else 0 fi

def cutoff():
    return 31337

def getThing(index):
    result = 3
    result = if index == 0 then 13 else result fi
    result = if index == 1 then 23 else result fi
    result = if index == 2 then 43 else result fi
    result = if index == 3 then 53 else result fi
    result = if index == 4 then 73 else result fi
    result = if index == 5 then 83 else result fi
    return result

def cubeThing(thing):
    return thing**3

def main(index):
    thing = getThing(index)
    thing = cubeThing(thing)
    return lt(cutoff(), thing)

This most recent main() is the mostly the same as the previous one that yielded 2197. The only difference between this new code and the previous is that, instead of returning the value, we compare 31337 to the value (just as in the very first example). When we call this newest main() with an argument of 0, we get an unexpected result!

Returned (~out): 1

It's telling us that 31337 is less than 2197! It seems that no matter the input to this code, the resulting value is 1. I have no idea what's happening. :) I suppose my question is: is there an issue with this code, or with ZoKrates itself?

Thanks,
โ€”J

Feature request: Some sort of multiple return

I'm currently attempting to implement SHA-256, and in order to do this I need to work on 32-bit words. Right now functions can only return a single value, making it impossible to encapsulate operations on these 32-bit words.

The two good solutions I can think of:

  1. There could be some sort of basic fixed-length array/tuple type, which would be a valid return type. (This is ideal, but I don't know how hard it's likely to be.)
def duplicate(x):
    return [x, x]

def main(x):
    y = duplicate(x)
    y[0] == x
    y[1] == x
  1. Functions could be allowed to return multiple values, with required destructuring assignment:
def duplicate(x):
    return x, x

def main(x):
    y, z = duplicate(x)
    y == x
    z == x

There are also less elegant solutions:

  1. Global variables could be used to store state.
y = 0
z = 0

def duplicate(x):
    y = x
    z = x

def main(x): 
    duplicate(x)
    y == x
    z == x
  1. There could be a macro system that inserted code in a way that allowed intentional shadowing.
macro duplicate():
    y = x
    z = x

def main(x): 
    y = 0
    z = 0
    duplicate()
    y == x
    z == x

Accept proving inputs as JSON

It would be good to accept proving inputs as a JSON file as I noticed people had problems working out and passing the right command-line arguments.

Using JSON for the raw inputs would avoid having to figure out the packing logic in the code that calls the prover, and would allow types from ZoKrates code to be automagically handled as the code changes.

e.g

def main(public value : int16, public flag : bool, private preimage : bytes32):
   ...

The inputs would be:

{
 "public" : {
    "value": 1234,
    "flag": true
 },
 "secret": {
    "preimage": "0x....."
 }

If you were going to support struct types, it would be something like:

struct Derp:
    value : int16
    flag : bool

def main(public derps : Derp[2]):
   ...

With JSON input:

{
 "public" : {
    "derps": [
       { 
           "value": 1234,
           "flag": true
       },
       { 
           "value": 1234,
           "flag": true
       }
    ]
 }

Note that I've made up typed variables for ZoKrates, because passing each individual bit at a time is a massive PITA. Likewise, with fixed-sized arrays of structs... it'd be really good to support these kinds of things as it'd mean that you don't have to do bits to int unpacking by hand, or handling the encoding logic yourself.

This would make EaseOfUse++

Dynamic scoping

Consider the following program:

def foo():
  a = b + 5
  return a

def bar():
  b = 2
  return foo()

def main(): 
  return bar()

Currently, it compiles and runs, returning 7. This means that in foo, b exists even though it's declared in bar. Scope is determined based on the execution (when foo is executed, we're in bar which defined b) not how the functions are defined (in the context of the definition of foo, b is not defined)

I'm not suggesting that this is a bug: some languages like Perl use dynamic scoping. However, a large majority uses static scoping (based on definitions, not execution) and that's what most developers would expect. I guess the questions could be:

  • Does ZoKrates benefit from dynamic scoping?
  • What would switching to static scoping involve?

Any feedback?

References:
https://msujaws.wordpress.com/2011/05/03/static-vs-dynamic-scoping/

Problems with division

It seems as there is a problem with division.

If using the code:
def main(a,b,c): d = (1000 / a) e = (1000 / b) f = (1000 / c) return ((d + e) + f)
and 1000, 500 and 5000 as a,b and c respectively I get a very odd result.

d and e do both get the expected values, but f is 8755297148735710088898562298102910035419345760166413737479281674630323398247 which is definitely what not the expected value.

Have I messed up or does it make sense to you?

Implement BLS12-381 precompile

@Schaeff has explained to me that the new BLS12-381 curve seems to be much faster for pairing and that the ZCash team has creating a new library in Rust for it: https://github.com/zkcrypto/pairing

It would be nice to figure out if that is true, but unfortunately it would require a new precompile on the mainnet.

However, since thee pairing library is in Rust and the ewasm project has current mainnet precompiles rewritten in Rust (https://github.com/ewasm/ewasm-precompiles) I think it would be extremely simple to compile the new pairing library and have it supported on the ewasm testnet.

I think this would be a really good opportunity to test these assumptions while utilising the ewasm testnet without a lot of effort put into it.

Setup runtime grows quadratic with number of variables

I believe this code is causing the setup step to run in quadratic time with number of variables.

https://github.com/JacobEberhardt/ZoKrates/blob/de577383775d1fa3fa4165e92d08010aab16347f/zokrates_core/src/r1cs.rs#L247-L261

Would it be possible to replace the Vector with a more efficient data-structure, e.g. a HashMap of vName->index combined with a nextIndex or something alike?

Please find callgrind performance traces attached (variables: 10108, constraints: 39264, inputs: 1).

screen shot 2018-09-03 at 16 36 09

callgrind.out.setup-step.zip

Panic while compiling add.code

When compiling https://github.com/JacobEberhardt/ZoKrates/blob/develop/examples/add.code using ./zokrates compile -i ... ,i get a panic

thread 'main' panicked at 'Semantic analysis failed with: a is undefined', src/main.rs:222:29
stack backtrace:
   0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
             at libstd/sys/unix/backtrace/tracing/gcc_s.rs:49
   1: std::sys_common::backtrace::_print
             at libstd/sys_common/backtrace.rs:71
   2: std::panicking::default_hook::{{closure}}
             at libstd/sys_common/backtrace.rs:59
             at libstd/panicking.rs:380
   3: std::panicking::default_hook
             at libstd/panicking.rs:396
   4: std::panicking::rust_panic_with_hook
             at libstd/panicking.rs:576
   5: std::panicking::begin_panic
             at libstd/panicking.rs:537
   6: std::panicking::begin_panic_fmt
             at libstd/panicking.rs:521
   7: zokrates::main
   8: std::rt::lang_start::{{closure}}
   9: std::panicking::try::do_call
             at libstd/rt.rs:59
             at libstd/panicking.rs:479
  10: __rust_maybe_catch_panic
             at libpanic_unwind/lib.rs:102
  11: std::rt::lang_start_internal
             at libstd/panicking.rs:458
             at libstd/panic.rs:358
             at libstd/rt.rs:58
  12: main
  13: __libc_st

The reason is that main method of add.code is missing argument. The code looks like this

def main():        // missing argument "a"
  b = a + 5
  c = a + b + a + 4
  d = a + c + a + b
  return b + c + d

It needs to look like this

def main(a):      // or def main(private a):
  b = a + 5
  c = a + b + a + 4
  d = a + c + a + b
  return b + c + d

Changing to above code makes that panic disappear and compilation, setup, etc work

Speed up CI

Builds are slow as cargo builds three times from a fresh cache.
Speed up Jenkins by caching cargo modules.

[Runtime Crash] Symbol splitting not working correctly in subroutines

Assume the following sample code I want to create a witness for (I stripped off meaningful things for simplicity):

def sub():
  foo = if 1 < 2 then 1 else 2 fi
  return 1

def main():
   return sub()

It compiles fine. However computing a witness leads to the following error:

thread 'main' panicked at 'no entry found for key', libcore/option.rs:917:5
note: Run with `RUST_BACKTRACE=1` for a backtrace.

In particular I believe that this line causes the crash. Printing var_name and inputs, I can see that:

Inputs: {"sub_i0o1_1_sym_0": 1, "sub_i0o1_1_sym_1": 2, "sub_i0o1_1_sym_2": 21888242871839275222246405745257275088548364400416034343698204186575808495615, "~one": 1}
Variable name: "sym_2"

sym_2 does not exist and we therefore crash. I assume that either sub_i0o1_1_sym_2 in inputs should be sym_2 (without the subroutine prefix) or sym_2 should be prefixed accordingly.

Guidance on circuit needed

I am trying to see if I can use ZoKrates in a scenario where a user can prove to the verifier that age is over 21 years without revealing the date of birth. I think its a good use case for zero-knowledge proof but like to understand the best way to implement it.

The circuit code (sample) takes the name of the user as public input(name attestation is done by a trusted authority like DMV and is a most likely combination of offline/online mechanism), then the date of birth which is a private input.

//8297122105 = "Razi" is decimal.
def main(pubName,private yearOfBirth, private centuryOfBirth):
  x = 0
  y = 0
  z = 0
  x = if centuryOfBirth == 19 then 1 else 0 fi
  y = if yearOfBirth < 98 then 1 else 0 fi
  z = if pubName == 8297122105 then 1 else 0 fi
  total =  x + y + z 
  result = if total == 3 then 1 else 0 fi
  
  return result 

Now, using ./target/release/zokrates generate-proof command get the output that can be used as an input toverifier.sol.

A = Pairing.G1Point(0x24cdd31f8e07e854e859aa92c6e7f761bab31b4a871054a82dc01c143bc424d, 0x1eaed5314007d283486826e9e6b369b0f1218d7930cced0dd0e735d3702877ac);
A_p = Pairing.G1Point(0x1d5c046b83c204766f7d7343c76aa882309e6663b0563e43b622d0509ac8e96e, 0x180834d1ec2cd88613384076e953cfd88448920eb9a965ba9ca2a5ec90713dbc);
B = Pairing.G2Point([0x1b51d6b5c411ec0306580277720a9c02aafc9197edbceea5de1079283f6b09dc, 0x294757db1d0614aae0e857df2af60a252aa7b2c6f50b1d0a651c28c4da4a618e], [0x218241f97a8ff1f6f90698ad0a4d11d68956a19410e7d64d4ff8362aa6506bd4, 0x2ddd84d44c16d893800ab5cc05a8d636b84cf9d59499023c6002316851ea5bae]);
B_p = Pairing.G1Point(0x7647a9bf2b6b2fe40f6f0c0670cdb82dc0f42ab6b94fd8a89cf71f6220ce34a, 0x15c5e69bafe69b4a4b50be9adb2d72d23d1aa747d81f4f7835479f79e25dc31c);
C = Pairing.G1Point(0x2dc212a0e81658a83137a1c73ac56d94cb003d05fd63ae8fc4c63c4a369f411c, 0x26dca803604ccc9e24a1af3f9525575e4cc7fbbc3af1697acfc82b534f695a58);
C_p = Pairing.G1Point(0x7eb9c5a93b528559c9b98b1a91724462d07ca5fadbef4a48a36b56affa6489e, 0x1c4e24d15c3e2152284a2042e06cbbff91d3abc71ad82a38b8f3324e7e31f00);
H = Pairing.G1Point(0x1dbeb10800f01c2ad849b3eeb4ee3a69113bc8988130827f1f5c7cf5316960c5, 0xc935d173d13a253478b0a5d7b5e232abc787a4a66a72439cd80c2041c7d18e8);
K = Pairing.G1Point(0x28a0c6fff79ce221fccd5b9a5be9af7d82398efa779692297de974513d2b6ed1, 0x15b807eedf551b366a5a63aad5ab6f2ec47b2e26c4210fe67687f26dbcc7434d);

Question

Consider a scenario when a user (say Razi) can take the proof above (probably in a form of a QR code) and scan it on a machine (confirms age is over 21) that will run the verifierTx method on the contract. Since the proof explicitly has "Razi" inside the proof and contract can verify the age without knowing the actual date of birth we get a better privacy. However, the challenge is now anyone else can reuse the proof since it was used within the transaction. One way to mitigate this issue is to make sure that either the proof is valid for a limited time or (just may good for one-time use). Another way is to ensure proof of user's identity ("Razi"), in a way that is satisfied beyond doubt (e.g. by confirming identity on blockchain etc.).

I hope the question and explanation make sense. Happy to elaborate more on this, so let me know.

License?

What is the ZoKrates license?

Verified event in Verifier contract causes TypeError in Truffle

Within the Truffle console, I've been interacting with my Verifier contract as follows

Verifier.deployed().then(instance => { return instance.verifyTx(A, A_p, B, B_p, C, C_p, H, K, I) })

Which causes the following error

TypeError: Cannot read property 'constructor' of undefined

I've found here that this issue is caused when a variable name is not given to a parameter in an event declaration; relative to the Verifier contract the problem looks like this

event Verified(string);

and can be fixed simply by adding a variable name

event Verified(string s);

Tested with Truffle v4.1.11 and Solidity v0.4.24

Intermediate representation for ZoKrates - portable circuits

The jsnark project uses an intermediate assembly-ish language to allow the circuits to be imported into libsnark:

Example:

input 0
input 1
nizkinput 3
nizkinput 4
nizkinput 5
output 6
add <3 4> out 0
mul <0 4> out 1
...

Opcodes:

  • add
  • mul
  • or
  • xor
  • zerop
  • split
  • const-mul-neg-
  • const-mul-
  • pack
  • assert

The JSnark circuit builder outputs to this format, and the xjsnark high-level language uses JSNark - and such compiles down to these opcodes.

I think opcodes like this are much simpler than the suggestions so far involving WebAssembly and JSON, because they can be quickly implemented and emulated over any field. So it can act as a portable format that both ZoKrates and JSnark could both compile to. Additionally it could serve as a uniform representation for circuits across Bellman and libsnark backends.

However, a problem is witness generation. Say there is the difference between user-input and intermediate variables, from the user input the intermediate variables must be calculated.

Secondly @Schaeff mentioned function support, where the 2nd stage would inline all of the functions to produce the final circuit.

example:

input 0
input 1
output 2

def x(a, b):
  assembly:
    local c
    add c a b
  return $c

call x(0, 1) 2

Translates to

input 0
input 1
output 2
add 2 <0 1> out 1 <2>

It would be nice to be able to support jsnark output as-is, but with a function layer ontop of it.

A compact binary representation could be something like:

  • uint8 - optype
  • uint32 - arg 1
  • uint32 - arg 2
  • ...

Where optype decides how many arguments are necessary?

Add user-defined directives

At a high level, it may be interesting for some users to write inline directives.
There is a security risk as the user has the responsibility to ensure the variables are constrained correctly, which we could make clear with unsafe blocks like Rust does

Thanks @jbaylina for the suggestion!

Error in witness computation using optimized code

After using --optimized compiler option, I get the following error while computing witness. The code works fine when --optimized is not used.

thread 'main' panicked at 'no entry found for key', libcore/option.rs:960:5
stack backtrace:
0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
at libstd/sys/unix/backtrace/tracing/gcc_s.rs:49
1: std::sys_common::backtrace::print
at libstd/sys_common/backtrace.rs:71
at libstd/sys_common/backtrace.rs:59
2: std::panicking::default_hook::{{closure}}
at libstd/panicking.rs:211
3: std::panicking::default_hook
at libstd/panicking.rs:227
4: std::panicking::rust_panic_with_hook
at libstd/panicking.rs:511
5: std::panicking::continue_panic_fmt
at libstd/panicking.rs:426
6: rust_begin_unwind
at libstd/panicking.rs:337
7: core::panicking::panic_fmt
at libcore/panicking.rs:92
8: core::option::expect_failed
at libcore/option.rs:960
9: <zokrates_core::flat_absy::FlatExpression>::solve
10: <zokrates_core::flat_absy::FlatExpression>::solve
11: <zokrates_core::flat_absy::FlatFunction>::get_witness
12: zokrates::main
13: std::rt::lang_start::{{closure}}
14: std::panicking::try::do_call
at libstd/rt.rs:59
at libstd/panicking.rs:310
15: __rust_maybe_catch_panic
at libpanic_unwind/lib.rs:105
16: std::rt::lang_start_internal
at libstd/panicking.rs:289
at libstd/panic.rs:374
at libstd/rt.rs:58
17: main
18: __libc_start_main
19:
../Makefile:26: recipe for target 'witness' failed

The `Parameter` type should only apply to the main function

Functions are functions, whether the arguments passed to them are public or not depends on the context, so shouldn't be hardcoded in their definition.

Maybe we should only have the concept of private and public for the main function.

Production ready date?

Any ideas when this will be production ready?

What needs to happen for that to happen and how can I help in the development of this project to help move things along?

Creating private ERC20 tokens

Would it be possible to create private ERC20 tokens using this project that hide user addresses and balances?

Has this been done yet? And if so, where?

Poor compilation performance due to linear lookup in scoped variables

I noticed that compilation times for larger .code files easily become long and ran a profiler on the compilation step of a ZoKrates debug build.

valgrind --tool=callgrind --dump-instr=yes --collect-jumps=yes --simulate-cache=yes ./zokrates compile -i <code file>

Looking at the results, I noticed that almost 60% of the time is spent in this line Iterator::find called from Checker::check_expression.

self.scope.iter().find(|v| v.id.id == variable) { ... }

Given that scope is already of type HashSet<ScopedVariable>, I was wondering if we could use constant time lookup via the get function instead of looping of the entire iterator with find? We would have to implement hash and eq on ScopedVariable to match only on id rather than both id and level.

Can you see a problem with this? Alternatively, would we somehow be able to predict the level of the variable we are looking for so that we could create a temporary ScopedVariable that matches the one in the HashSet (without creating custom eq, hash methods)?

I changed the code locally as suggested and noticed a dramatic reduction in CPU instructions (81 million -> 34 million) for my example. However, I'm not sure if I'm missing something here and am introducing a problem somewhere else.

Please find attached the .code file as well as profiling results for the original and optimised code. I'm happy so submit a pull request if there is no concern with changing this.

issue.zip

Unexpected result for < operator

I'm probably lacking some mathematical background here, but I was surprised to see that the following program

def main():
  return if 0 < 21888242871839275222246405745257275088548364400416034343698204186575808495616 then 1 else 0 fi

returns 0. I would have expected it to return 1, since 0 should be smaller than the large number.

Does this have something to do with interpreting the larger number as a signed integer (-1)? If so, where would be the "underflow point" for which i < i-1?

I'm trying to write a proof that is dealing with potentially very large unsigned integers and would like to know what the highest number n is, for which 0 < n.

Unable to use the exported smart contract

I am using truffle to export the generated smart contract for factorization.code. Versions

Truffle v4.1.5 (core: 4.1.5)
Solidity v0.4.21 (solc-js)

I am able to compile (with warning though but are addressed here #49) and deploy the contract but when i try to test it, i get error

...../contracts/Verifier.sol:1
(function (exports, require, module, __filename, __dirname) { pragma solidity ^0.4.14;

The test is here and the contract is here

Also i don't understand which contracts are being called at
https://github.com/lovesh/ZoKrates/blob/develop/src/verification.rs#L49,
https://github.com/lovesh/ZoKrates/blob/develop/src/verification.rs#L64 and
https://github.com/lovesh/ZoKrates/blob/develop/src/verification.rs#L91

As i understand, the second argument to call is supposed to be contract address, but they don't seem like contract address, are they? If yes, then can you please point me to those contracts or relevant sections of solidity documentation.
Thanks

Building a docker image seems to fail on OSX host system

I have successfully built the most recent develop branch inside of a vagrant ubuntu/artful64 vm but repeatedly fail to build the image from my mac osx host. The command I run is docker build . and the repository is clean (i.e. check out the source, run the command, nothing else in between).

I have modified the Dockerfile to add the --verbose flag to the cargo invocation and this is the error I get when running this straight off my OSX system:

   Compiling serde_derive v1.0.27
     Running `rustc --crate-name serde_derive /root/.cargo/registry/src/github.com-1ecc6299db9ec823/serde_derive-1.0.27/src/lib.rs --crate-type proc-macro --emit=dep-info,link -C prefer-dynamic -C opt-level=3 --cfg 'feature="default"' -C metadata=91de777f69207123 -C extra-filename=-91de777f69207123 --out-dir /root/ZoKrates/target/release/deps -L dependency=/root/ZoKrates/target/release/deps --extern serde_derive_internals=/root/ZoKrates/target/release/deps/libserde_derive_internals-2720d1df1545453b.rlib --extern syn=/root/ZoKrates/target/release/deps/libsyn-3f141fcf71baed5d.rlib --extern quote=/root/ZoKrates/target/release/deps/libquote-9c21d2aa28aebe6f.rlib --cap-lints allow`
error: Could not compile `serde_derive`.

Caused by:
  process didn't exit successfully: `rustc --crate-name serde_derive /root/.cargo/registry/src/github.com-1ecc6299db9ec823/serde_derive-1.0.27/src/lib.rs --crate-type proc-macro --emit=dep-info,link -C prefer-dynamic -C opt-level=3 --cfg feature="default" -C metadata=91de777f69207123 -C extra-filename=-91de777f69207123 --out-dir /root/ZoKrates/target/release/deps -L dependency=/root/ZoKrates/target/release/deps --extern serde_derive_internals=/root/ZoKrates/target/release/deps/libserde_derive_internals-2720d1df1545453b.rlib --extern syn=/root/ZoKrates/target/release/deps/libsyn-3f141fcf71baed5d.rlib --extern quote=/root/ZoKrates/target/release/deps/libquote-9c21d2aa28aebe6f.rlib --cap-lints allow` (signal: 11, SIGSEGV: invalid memory reference)

Parser blow up for long linear combinations

Parsing this simple program:

def main():
	a = 1+2*3+3*4+4*5+5*6+6*7+7*8+8*9+9*10+10*11+11*12+12*13+13*14
	return 1

takes a surprisingly long time, which I identified to be due to a problem in the parser which jumps backwards a lot

testing proof with web3js

I have been playing with ZoKrates for a few days but I can't achieve a verification process with a true statement. It is alway FALSE I tried to follow the tutorial of the readme but I encountered some difficulties: the verification always returns "false". I mean, of course, I should use the toolbox with a wrong way

This is the basic code I want to test:

def main(x,private s1,private s2):
    s1 + s2 + x == 15
    return 1

Then when I generate proof I have this output:

Generating proof...
Using Witness: {"~one": 1, "x": 5, "~out_0": 1, "s2": 5, "s1": 5}
Public inputs: [1, 5, 1]
Private inputs: [5, 5]
* Elements of w skipped: 0 (-nan%)
* Elements of w processed with special addition: 0 (-nan%)
* Elements of w remaining: 0 (-nan%)
* Elements of w skipped: 0 (-nan%)
* Elements of w processed with special addition: 0 (-nan%)
* Elements of w remaining: 0 (-nan%)
* Elements of w skipped: 0 (0.00%)
* Elements of w processed with special addition: 1 (25.00%)
* Elements of w remaining: 3 (75.00%)
* Elements of w skipped: 0 (0.00%)
* Elements of w processed with special addition: 1 (25.00%)
* Elements of w remaining: 3 (75.00%)
* G1 elements in proof: 7
* G2 elements in proof: 1
* Proof size in bits: 2294
Proof:
A = 0x17ae0464d4c0d1937fee027b520ca9ec7ee4f2abf70b52a75c636d6735005392, 0x281134f906ab1cb3011cb6207a1f9ef5398045af52c3eff8e9db9f50c8cf3828
A_p = 0x1ac693cdd14a1206f930729a929b3b39721f838446061af6311c4ed30c428426, 0x2712e90c78ec9e0e5ccf3356e23855484c4073bb274194635b612b63f4ac8be3
B = [0x883a4f310a3966a5cb139b59288c78aa8a8a9a8b4bf48792420d5184f8fb8b5, 0x201d60787fd856c24e7b45dab7cb41a79ff348153683dbf82b5d77d14e168ae5], [0x1d9ccf0e5d091b85a795d74abc13625e531cb65115589b999c9c0e05b7310920, 0x21a3beba1014556c091197668c9380cc37e420b4232fa5c35a175ee00bfe92f4]
B_p = 0x1d0c580e2431894c97e6bee5de2e396477beabebeb4606c21d241328d0ca139d, 0x2add4d48ef20738cf6540cc530bf80948bd6cb8b180cf4a3ec412e0dc58fe3de
C = 0x20ba1cacf4ebbc3c1c29d11946b1c38151cb44d0803d628fa69e1ae8e930e7c7, 0x1dc6686abe23aa65b1653fab516386b86d7deae2ac817cf7fb3d89ad4d1da8ca
C_p = 0xb292b7ab8b91c84eb61338fa9837465d94e3e82c1e029c55b4d754161242b13, 0x15f60d3a7192a31f6da6804e960cbd13198a710f14c4860fd5ea1453eb2cf131
H = 0x2621bd887a4e502ae5d9660a56702be8a7567bee0507d8af711be5fca888ff88, 0x2e905b72b811929ea2475d8c0df0a5815e329aebe787a37cf62a60ba4dad0c5c
K = 0xf1bd7f2d6fe7efcb5480bd8743c359153dc73153039f0c76c90b62431ca1ac2, 0x151b78bf375d6d20a2f242e70db41d25183a594632e553f97d27570d15551ff
generate-proof successful: true

(I used as value for x = 5, s1 = 5, s2 = 5 )

Here I am confused, the length of public inputs is 3 but in my verifier.sol generated the array expected in verifyTx is of length 2 ...

Then, I deploy verifier.sol & SumsToFifteen.sol (please find them attached), and I try to test the result of my proof with the web3js script verifier.js (but it is always false):

proof: 0
success: false

Please, could you help me to find a way to make all this stuff working?

Thank's in advance


Note:

  • in verifier.js I try all kind of mix for I (I=[1, 5 ,1], I=[1, 5], I=[5,1], ...)

    eth.contract(abi).at("0xfc1684a8af3e6bf532482c356e5b2cef9cad144f")

    referenced obviously to the contract address of the SumsToFifteen.sol

  • I've also tried to change the length of the input both files SumToFifteen.sol and verify.sol to 2 without any success


verifier.js
verifier.sol
SumsToFifteen.sol

Random number generation

Is it possible to generate a random number?. I want to generate random number between a specific range.

Unexpected results evaluating if/else statements on latest master

On latest master (da5b13f) the following program fails:

def main():
  b = if 1 < 2 then 0 else 1 fi
  b == 0
  return 1

with

Condition not satisfied: b should equal 0, but was 3 0

I understand that there is still an open issue with < (#99), but I would at least expect b to be either 0 or 1 not 3

Also checking out 3c36637 the same example above works fine.

Fixed lenght array support ?

Hi

Thanks a lot for this great implementation and Ethereum integration!

In the examples I can't see the use of arrays so I wanted to ask if I can pass arrays into functions of fixed length. Something like:

def sum(array): // array is of size 10
    sum = 0
    for i in 1..10 do
        sum = sum + array[i]
    endfor
    return sum

Make private inputs explicit

Problem

The way private inputs are treated is different from public ones:

  • Private inputs are implicit, public inputs are explicit:
def main(c):
  c == a * b
  return 1
  • Public inputs are passed as arguments in compute-witness, while private inputs are passed interactively
  • It makes it hard to use compute-witness programatically
  • It gives no way to list private inputs without solving the R1CS

Solution

We think they should be explicit:

def main(c | a,b):
  c == a * b
  return 1

Roadmap

  1. Make it possible to pass private inputs as arguments in compute-witness rather than interactively (the interactive mode should be activated by a flag)
  2. Make it possible to specify explicit private inputs in .code files
  3. Ban implicit private inputs from .code files

Thoughts welcome :)

[Runtime Crash] Cannot re-assign function parameter when it is used in assignment

Assume the following sample code

def sub(a):
  a = a + 3
  return a

def main():
   a = 4
   return sub(a)

It compiles fine, however when computing a witness it crashes with:

thread 'main' panicked at 'Variable "sub_i1o1_1_a" is undeclared in inputs: {"a": 4, "sub_i1o1_1_param_0": 4, "~one": 1}', src/flat_absy.rs:302:25
note: Run with `RUST_BACKTRACE=1` for a backtrace.

I assume it has something to do with reassigning a function parameter while also using it in the assignment. Seems like a pretty edgy case, but something that should be allowed?

Workaround was to introduce a separate variable instead of reassigning a.

cargo test fails on the docker image

When I follow the README, and enter the docker image,

root@5a2636025815:~/ZoKrates# cargo build --release
root@5a2636025815:~/ZoKrates# cargo build

succeed, but cargo test fails with

root@5a2636025815:~/ZoKrates# cargo test          
<snip>
error[E0308]: mismatched types
   --> src/semantics.rs:562:37
    |
562 |         assert_eq!(checker.check_function(bar), Err("a is undefined".to_string()));
    |                                           ^^^
    |                                           |
    |                                           expected reference, found struct `absy::Function`
    |                                           help: consider borrowing here: `&bar`
    |
    = note: expected type `&absy::Function<_>`
               found type `absy::Function<field::FieldPrime>`

Implement a github import resolver

Once #110 is merged, it will be really easy to implement other import resolvers. That means that:

import github.com/my/rep/hash.code as my_hash

becomes possible.

Create a new crate similar to zokrates_fs_resolver which resolves Github files.

panick at 'no entry found for key'

Already mentioned this issue in gitter.im chat, but also posting it here so others can see it aswell. Been playing around with the less than "<" operator, to determine if ZoKrates in its current state is capable of performing taxation in a proof-of-concept. However, I met a error in the development.

The source code is:

def wtax(debt,wealth):
  x = if wealth < debt then 0 else (wealth-debt) fi
  return x

def main(debt, wealth):
  tax = wtax(debt,wealth)
  return tax

Although my application compiles fine, it gives the following error when I try to compute witnesses:

root@de4db328ebdf:~/ZoKrates/target/release/test# ../zokrates compute-witness -a 2 500000
Computing witness for:
def main(debt,wealth):
...
thread 'main' panicked at 'no entry found for key', libcore/option.rs:917:5
stack backtrace:
0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
at libstd/sys/unix/backtrace/tracing/gcc_s.rs:49
1: std::sys_common::backtrace::_print
at libstd/sys_common/backtrace.rs:71
2: std::panicking::default_hook::{{closure}}
at libstd/sys_common/backtrace.rs:59
at libstd/panicking.rs:380
3: std::panicking::default_hook
at libstd/panicking.rs:396
4: std::panicking::rust_panic_with_hook
at libstd/panicking.rs:576
5: std::panicking::begin_panic
at libstd/panicking.rs:537
6: std::panicking::begin_panic_fmt
at libstd/panicking.rs:521
7: rust_begin_unwind
at libstd/panicking.rs:497
8: core::panicking::panic_fmt
at libcore/panicking.rs:71
9: core::option::expect_failed
at libcore/option.rs:917
10: <zokrates::absy::Expression>::solve
11: <zokrates::absy::Expression>::solve
12: <zokrates::absy::Function>::get_witness
13: zokrates::main
14: std::rt::lang_start::{{closure}}
15: std::panicking::try::do_call
at libstd/rt.rs:59
at libstd/panicking.rs:479
16: __rust_maybe_catch_panic
at libpanic_unwind/lib.rs:102
17: std::rt::lang_start_internal
at libstd/panicking.rs:458
at libstd/panic.rs:358
at libstd/rt.rs:58
18: main
19: __libc_start_main
20:

When i pull the logic of def wtax(debt,wealth) back into main, the application works fine.

DSL language grammar and documentation

Thanks for the great effort, ZoKrates is really awesome! I'm wondering that:

  1. is there any documentation of the grammar of the DSL ZoKrates uses? Or how could I contribute to come up with one if currently not available, where should I learn about the grammar details?

  2. Also I'm wondering that is it possible to bypass this specific DSL and directly compiles solidity code? Forgive me as I'm not too clear about the complexity and workload behind this, can you please elaborate?

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.