Giter Club home page Giter Club logo

jsnark's Introduction

jsnark

This is a Java library for building circuits for preprocessing zk-SNARKs. The library uses libsnark as a backend (https://github.com/scipr-lab/libsnark), and can integrate circuits produced by the Pinocchio compiler (https://vc.codeplex.com/SourceControl/latest) when needed by the programmer. The code consists of two main parts:

  • JsnarkCircuitBuilder: A Java project that has a Gadget library for building/augmenting circuits. (Check the src/examples package)
  • libsnark/jsnark_interface: A C++ interface to libsnark which accepts circuits produced by either the circuit builder or by Pinocchio's compiler directly.

Updates:

  • The jsnark library now has several cryptographic gadgets used in earlier work (Hawk and C0C0). Some of the gadgets like RSA and AES were improved by techniques from xJsnark. The gadgets can be found in src/examples/gadgets.
  • xJsnark, a high-level programming framework for zk-SNARKs is available here. xJsnark uses an enhanced version of jsnark in its back end, and aims at reducing the background/effort required by low-level libraries, while generating efficient circuits from the high-level code. Sample examples can be found in this page.

Prerequisites

  • Libsnark prerequisites
  • JDK 8 (Higher versions are also expected to work. We've only tested with JDKs 8 and 12.)
  • Junit 4
  • BouncyCastle library

For Ubuntu 14.04, the following can be done to install the above:

  • To install libsnark prerequisites:

    $ sudo apt-get install build-essential cmake git libgmp3-dev libprocps3-dev python-markdown libboost-all-dev libssl-dev

Note: Don't clone libsnark from https://github.com/scipr-lab/libsnark. Make sure to use the modified libsnark submodule within the jsnark cloned repo in the next section.

  • To install JDK 8:

    $ sudo add-apt-repository ppa:webupd8team/java

    $ sudo apt-get update

    $ sudo apt-get install oracle-java8-installer

Verify the installed version by java -version. In case it is not 1.8 or later, try $ sudo update-java-alternatives -s java-8-oracle

  • To install Junit4:

    $ sudo apt-get install junit4

  • To download BouncyCastle:

    $ wget https://www.bouncycastle.org/download/bcprov-jdk15on-159.jar

jsnark Installation Instructions

  • Run $ git clone --recursive https://github.com/akosba/jsnark.git

  • Run:

    $ cd jsnark/libsnark

    $ git submodule init && git submodule update

    $ mkdir build && cd build && cmake ..

    $ make

The CMakeLists files were modified to produce the needed executable for the interface. The executable will appear under build/libsnark/jsnark_interface

  • Compile and test the JsnarkCircuitBuilder project as in the next section..

Running and Testing JsnarkCircuitBuilder

To compile the JsnarkCircuitBuilder project via command line, from the jsnark directory:

$ cd JsnarkCircuitBuilder
$ mkdir -p bin
$ javac -d bin -cp /usr/share/java/junit4.jar:bcprov-jdk15on-159.jar  $(find ./src/* | grep ".java$")

The classpaths of junit4 and bcprov-jdk15on-159.jar may need to be adapted in case the jars are located elsewhere. The above command assumes that bcprov-jdk15on-159.jar was moved to the JsnarkCircuitBuilder directory.

Before running the following, make sure the PATH_TO_LIBSNARK_EXEC property in config.properties points to the path of the run_ppzksnark executable.

To run a simple example, the following command can be used

$ java -cp bin examples.generators.SimpleCircuitGenerator

To run one of the JUnit tests available:

$ java -cp bin:/usr/share/java/junit4.jar org.junit.runner.JUnitCore  examples.tests.hash.SHA256_Test

Some of the examples and tests will require bcprov-jdk15on-159.jar as well to be added to the classpath.

Note: An IDE, e.g. Eclipse, or possibly the ant tool can be used instead to build and run the Java project more conveniently.

Examples included

Simple Examples

  • Basic Circuit Example: SimpleCircuitGenerator.java. This shows a circuit that computes very simple expressions.
  • Basic Gadget Example: DotProductGadget.java. This is a gadget for computing the dot product of two vectors. The gadget is used in DotProductCircuitGenerator.java.
  • Gadgets with witness computations done outside the circuit: FieldDivisonGadget.java, ModGadget.java. This way of writing circuits is useful when verification is more efficient than computation, and when the prover witness value can be inferred automatically in the circuit. Note the usage of specifyProverWitnessComputation(..). This must be positioned before the steps where the witness is used.
  • Pinocchio Integration: PinocchioGadget.java and AugmentedAuctionCircuitGenerator.java. The Pinocchio gadget can be used to use compiled circuits by the Pinocchio compiler as gagdets. AugmentedAuctionCircuitGenerator.java shows how to use a compiled Auction circuit by Pinocchio, and augment it with other manually-developed gadgets. This can help in the cases where the programmer needs to take care only of the bottleneck parts of the circuits.

Cryptographic Primtives

Several cryptographic gadgets spanning hashes, block ciphers, key exchange, public key encryption and signatures can be found in src/examples/gadgets. We list some notes regarding few gadgets below:

  • SHA256 gadget: This is a manually-optimized SHA256 Gadget for variable-length input with a padding option. The code is written to be similar to how SHA256 is written in C or Java, except for three main things: keeping track of bitwidth, manual optimizations for computation of ch and maj, and the explicit handling of overflows (A more recent work (xJsnark) reduces/eliminates the need for such differences, while still generating optimized outputs). The current SHA256 gadget implementation in jsnark costs about 25650 constraints for one block depending on the number and the bitwidth of the input wires (Further minor optimizations to the existing implementation in jsnark are possible).
  • RSA gadgets: This includes public key encryption gadgets based on both PKCS #1 V2.2 (OAEP) and PKCS #1 v1.5, and also a signature gadget using PKCS #1 v1.5. Internally, these gadgets used the long integer optimizations used in xJsnark.
  • Block cipher gadgets: This includes optimized implementations for AES, Speck and Chaskey ciphers.
  • Hybrid Encryption Example: The circuit main file is in HybridEncryptionCircuitGenerator.java. The circuit uses the gadgets defined in examples/gadgets/diffieHellmanKeyExchange and examples/gadgets/blockciphers, which are for key exchange (using field extension) and symmetric encryption using the speck cipher. Other variants will be added in the future.

Writing Circuits using jsnark

To summarize the steps needed:

  • Extend the CircuitGenerator class.
  • Override the buildCircuit() method: Identify the inputs, outputs and prover witness wires of your circuit, and instantiate/connect gadgets inside.
  • Override the generateSampleInput() method: Specify how the values of the input and possibly some of the free prover witness wires are set. This helps in quick testing.
  • To run a generator, the following methods should be invoked:
    • generateCircuit(): generates the arithmetic circuit and the constraints.
    • evalCircuit(): evaluates the circuit.
    • prepFiles(): This produces two files: <circuit name>.arith and <circuit name>.in. The first file specifies the arithemtic circuit in a way that is similar to how Pinocchio outputs arithmetic circuits, but with other kinds of instructions, like: xor, or, pack and assert. The second file outputs a file containing the values for the input and prover free witness wires. This step must be done after calling evalCircuit() as some witness values are computed during that step.
    • runLibsnark(): This runs the libsnark interface on the two files produced in the last step. By default, this method runs the r1cs_ppzksnark proof system implemented in libsnark. For other options see below.
  • Note: In the executing thread, use one CircuitGenerator per thread at a time. If multiple generators are used in parallel, each needs to be in a separate thread, and the corresponding property value in config.properties need to be adapted.

Running circuit outputs on libsnark

Given the .arith and the .in files, it's possible to use command line directly to run the jsnark-libsnark interface. You can use the executable interface run_ppzksnark that appears in jsnark/libsnark/build/libsnark/jsnark_interface to run the libsnark algorithms on the circuit. The executable currently allows to run the proof systems r1cs_ppzksnark (default) and r1cs_gg_ppzksnark implemented in libsnark. To run the first, the executable just takes two arguments: the arithmetic circuit file path, and a sample input file path. To run the r1cs_gg_ppzksnark proof system [Gro16], the first argument should be gg, followed by the arithmetic circuit file path, and the sample input file path.

Further Notes

The gadget library of jsnark shares some similarities with the C++ Gadget library of libsnark, but it has some options that could possibly help with writing optimized circuits quickly without specifying all the details. If the reader is familiar with the gadget libraries of libsnark, here are some key points to minimize confusion:

  • No need to maintain a distinction between Variables, LinearCombinations, ... etc. The type Wire can be used to represent Variables, LinearCombinations, Constants, .. etc. The library handles the mapping in a later stage.
  • Instead of having the notion of primary input and auxiliary input for representing variables, wires in jsnark can be labeled anywhere as either input, output, prover witness wires. Both the input and output wires are public and seen by the verifier (this corresponds to the primary input in libsnark). The prover witness wires refer to the free input variables provided by the prover. This is in some sense similar to the way Pinocchio's compiler classifies wires.
  • Each Gadget in libsnark requires writing and calling two methods: generateConstraints() to specify the r1cs constraints, and generateWitness() to invoke the witness computation. In jsnark's builder, applying primitive operations on wires generates constraints automatically. Additionally, the witness computation is done automatically for primitive operations, and does not need to be explicitly invoked, except in the case of prover witness computation that has to be done outside the circuit, e.g. the FieldDivisionGadget example.
  • Jsnark applies caching and other techniques during circuit construction to cancel unneeded constraints. This helps in code reusability when changing input variables wires to carry constant values instead. This also helps in reducing the complexity when writing optimized circuits. One example is the maj calculation in the SHA256 gadget, in which jsnark detects similar operations across the loop iterations with little effort from the programmer, resulting in more than 1000 gates savings. CachingTest.java also illustrates what cases caching can help with.

Running circuits compiled by Pinocchio on libsnark

  • To use Pinocchio directly with libsark, run the interface executable run_ppzksnark on the <circuit name>.arith and <circuit name>.in files. The <circuit name>.in should specify the hexadecimal value for each input and nizkinput wire ids, in the following format: id value, each on a separate line.
  • It is important to assign 1 to the wire denoted as the one wire input in the arithmetic file.

Disclaimer

The code is undergoing more testing and integration of other features. The future versions of this library will include more documentation, examples and optimizations.

Author

This code is developed and maintained by Ahmed Kosba [email protected]. Please email for any questions.

jsnark's People

Contributors

akosba avatar bitcartel avatar mariogemoll 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

jsnark's Issues

verifying proof on blockchain

Hi.Can a prover put her proof that has created using jsnark on blockchain and is there any smart contract auto created by jsnark that can verify these proofs?I mean something like what Zokrates does.

Questions about RSAEncryptionCircuitGenerator

Hi akosba, I am learning about RSAEncryptionCircuitGenerator and I would appreciate if you could please clarify the following questions.
My idea is that for RSA zero-knowledge proof, the privKey and the plainText should be private input, the pubKey and the cipherText should be public input. The prover can use the private input and the public input to generate proof, and the verifier can only use the public input and proof to verify (pk, vk are ignored here). But I don't understand much about this generator. This class has only private input inputMessage and randomness, while cipherText is used as output. What I want to ask is, is the pubKey (and the cipherText) not needed here as public input, in other words, is this circuit making a commitment to inputMessage and randomness in RSA rather than the entire encryption process?
In addition, if one has the value of public input, how can one recover the primary_input in libsnark to achieve validation without the verifier knowing the private input?

How to initialize a number on the prime field?

I was testing the circuit evaluation, and I am trying to initialize some random number on the prime field by doing this in jsnark/libsnark/src/CircuitReader.cpp:

FieldT a = 10000000000000;

When I do a.print(), I got some garbage value. But when I run it on a real circuit and trying to print out some of the wire values, it actually works. Did I do something wrong?

libsnark fails for circuits with checkNonZero depending on execution order

Hi!

I recently ran into an issue when creating a circuit in which checkNonZero gets called on wires whose values themselves depend on the results of calls to checkNonZero. The jsnark circuit generation and evaulation work without any issues, but when libsnark gets called, it often fails with the error message The constraint system is not satisifed by the value assignment - Terminating.

The strange part is that whether libsnark fails or not seems to depend on the execution order / order of operations in circuit.arith. For instance, in the minimal(-ish) example I've included below, sumPrime.add(cPrime) works just fine while cPrime.add(sumPrime) causes the aforementioned error in libsnark. If I replace calls to checkNonZero with a gadget that simply ORs all bit wires together, I'm also unable to reproduce the libsnark exception.

I think the root cause of this issue is how NonZeroCheckBasicOp is implemented in CircuitReader.cpp. In addNonzeroCheckConstraint and mapValuesToProtoboard, there seems to be an assumption that when the non-checkNonZero circuit inputs are set, all inputs of checkNonZero are present and can be used to compute the value of an auxiliary wire, which ultimately doesn't hold if the inputs of checkNonZero themselves depend on the outputs of other calls to checkNonZero.

Given that NonZeroCheckBasicOp already has 2 output wires and the order of operations is correct inside jsnark, wouldn't it be possible to define the required auxiliary wire as a witness wire, assign its value in NonZeroCheckBasicOp.compute, and then just read in that value in libsnark? If you'd like, I could try to implement this in both jsnark and libsnark and create a pull request for both on your repos 😄

Thank you very much for your work on this project!

Minimal example:

import circuit.eval.CircuitEvaluator;
import circuit.structure.CircuitGenerator;
import circuit.structure.Wire;

public class MinimalExample extends CircuitGenerator {

	public static void main(String[] args) {
		MinimalExample example = new MinimalExample();
		example.generateCircuit();
		example.evalCircuit();
		example.prepFiles();
		example.runLibsnark();
	}

	private Wire a, b, c;

	public MinimalExample() {
		super("MinimalExample");
	}

	@Override
	protected void buildCircuit() {
		a = createInputWire("a");
		b = createInputWire("b");
		c = createInputWire("c");

		Wire aPrime = a.checkNonZero("a nonzero"); // = 0
		Wire bPrime = b.checkNonZero("b nonzero"); // = 0
		Wire sumPlusOne = aPrime.add(bPrime, "sum").add(1, "sum + 1"); // = 1
		Wire sumPrime = sumPlusOne.sub(sumPlusOne.checkNonZero("sum nonzero")); // = 0
		Wire cPrime = c.checkNonZero("c nonzero"); // = 0

		// Works
		// Wire resultPlusOne = sumPrime.add(cPrime, "result").add(1, "result + 1"); // = 1

		// Doesn't work
		Wire resultPlusOne = cPrime.add(sumPrime, "result").add(1, "result + 1"); // = 1

		addOneAssertion(resultPlusOne, "result + 1 == 1");
	}

	@Override
	public void generateSampleInput(CircuitEvaluator evaluator) {
		evaluator.setWireValue(a, 0);
		evaluator.setWireValue(b, 0);
		evaluator.setWireValue(c, 0);
	}
}

Output:

Running Circuit Generator for < MinimalExample >
Circuit Generation Done for < MinimalExample >  
 	 Total Number of Constraints :  9
 	 Total Number of Wires : 19
Running Circuit Evaluator for < MinimalExample >
Circuit Evaluation Done for < MinimalExample >



-----------------------------------RUNNING LIBSNARK -----------------------------------------
Reset time counters for profiling
(enter) Parsing and Evaluating the circuit 	[             ]	(0.0000s x0.99 from start)
(leave) Parsing and Evaluating the circuit 	[0.0001s x1.00]	(0.0001s x1.00 from start)
Translating Constraints ... 
	Constraint translation done
Note: Protoboard Not Satisfied .. 
Assignment of values done .. 
Num constraints: 9
constraint 5 (no annotation) unsatisfied
<a,(1,x)> = 1
<b,(1,x)> = 0
<c,(1,x)> = 1
constraint was:
terms for a:
    1 * 0
    x_1 * 1
    where x_1 (no annotation) was assigned value 1
      i.e. negative of 21888242871839275222246405745257275088548364400416034343698204186575808495616
    x_6 * 1
    where x_6 (no annotation) was assigned value 0
      i.e. negative of 0
    x_9 * 1
    where x_9 (no annotation) was assigned value 0
      i.e. negative of 0
terms for b:
    1 * 0
    x_13 * 1
    where x_13 (no annotation) was assigned value 0
      i.e. negative of 0
terms for c:
    1 * 0
    x_12 * 1
    where x_12 (no annotation) was assigned value 1
      i.e. negative of 21888242871839275222246405745257275088548364400416034343698204186575808495616
The constraint system is  not satisifed by the value assignment - Terminating.

(edit:) The generated circuit file:

total 19
input 0			 # The one-input wire.
const-mul-0 in 1 <0> out 1 <1>
input 2			 # a
input 3			 # b
input 4			 # c
zerop in 1 <2> out 2 <5 6> 		# a nonzero
zerop in 1 <3> out 2 <7 8> 		# b nonzero
add in 2 <6 8> out 1 <9> 		# sum
add in 2 <9 0> out 1 <10> 		# sum + 1
zerop in 1 <10> out 2 <11 12> 		# sum nonzero
const-mul-neg-1 in 1 <12> out 1 <13>
add in 2 <10 13> out 1 <14>
zerop in 1 <4> out 2 <15 16> 		# c nonzero
add in 2 <16 14> out 1 <17> 		# result
add in 2 <17 0> out 1 <18> 		# result + 1
assert in 2 <18 0> out 1 <0> 		# result + 1 == 1

JAVA Version

Do we really need JAVA 8? Or can we go with JAVA current?

Floating point exception (core dumped)

When i call the interface "run_ppzksnark", i set params described in doc, file name of .arirth and .in; However i get the error info :Floating point exception (core dumped); I just use the output file of SimpleCircuitGenerator as param of the interface. Does any one know how to fix it?

Computing scalar multiplication using a negated scalar, on the Elliptic Curve

Hi @akosba,

I am using the arithmetic operations on the elliptic curve provided in the ECDHKeyExchange gadget in jsnark, in order to implement a circuit which computes some linear operations on Elgamal encryption in the exponent, carried out in the elliptic curve domain.

Out of the three basic arithmetic operations on elliptic curves (i.e. addition of two points, multiplication of a point by a scalar and negation of a point), ECDHKeyExchange gadget only uses the first two operations. In my circuit, given a positive scalar 'a' (which is a secret input to the circuit) and a point 'P' (which is a public input to the circuit), I need to compute (-a).P inside the circuit (i.e. the result of multiplying 'P' by negated 'a').

Could you please advice what is the recommended way to do this in jsnark? Is it fine to first compute the scalar multiplication a.P and then negate the resulting point? Or, should I first negate the scalar, and then perform scalar multiplication? I followed the first approach, by introducing a 'negateAffinePoint' function as below, because I am not sure how to do it using the latter approach in jsnark. I would appreciate a lot your insight on this.

AffinePoint negateAffinePoint(AffinePoint p){
return new AffinePoint(p.getX(), p.getY().mul(-1));
}

Thank you very much.

toturial

Hi.I want to use jsnark to prove that I know a value x that enc(x) == y that y is a public value.but actually I have lots of problem in how to start. Isn't there any useful tutorial that can help me how to do this step by step?

LongElement multiplication without creating prover witness wires.

Hi,

In this line: https://github.com/akosba/jsnark/blob/master/JsnarkCircuitBuilder/src/circuit/auxiliary/LongElement.java#L238

a witness wire array is created when multiplying a LongElement with another.

This has the effect of creating several secret input variables, which get put together with the real user-provided secret inputs of the circuit.

Is there a way to perform the multiplication without having these generated variables as secret or even public input ?

cmake failed

-- Checking for module 'libcrypto'
-- No package 'libcrypto' found
CMake Error at /usr/local/Cellar/cmake/3.12.1/share/cmake/Modules/FindPkgConfig.cmake:436 (message):
A required package was not found

Clarifying the use of the input parameter 'bitwidthPerInputElement' in SHA256 gadget

Hi Ahmed @akosba

Could you please clarify why 'bitwidthPerInputElement' is given as user input in SHA256 gadget? Shouldn't it always be 8 bits? Are there any use cases where it could be different than 8 bits?

I actually tried to make use of this parameter to set 16 hexdigits long words to an input wire (i.e bitwidthPerInputElement=64bits) of the SHA256 gadget. However, the output digest I got in that case is different from the case where I set 2 hexdigits long words (i.e bitwidthPerInputElement=8bits) to an input wire of the SHA256 gadget. In both the cases, I used the same hexdigit string (of length 128) derived from the same character string (of length 64).

Could you please clarify if it is valid to set 'bitwidthPerInputElement' to any value other than 8 and if so, is it expected that the output digest changes for different 'bitwidthPerInputElement' values, although we use the same original string?

Thank you very much!

What License is this?

Can you put it under MIT or GPLv3?

edit:

Ok, if there is no License, the code apparently seems to be in the public domain, which is fine with me also.

Questions about RSAEncryptionV1_5_Gadget

Hi Ahmed @akosba

I have studied the RSAEncryptionV1_5_Gadget and I would appreciate if you could please clarify the following two questions.

  1. I found in the comments that the gadget assumes a hard coded public exponent of 0x10001. If I want to give public exponent as input to the gadget, where should I change the encryption logic?
    According to my understanding, following is the code snippet that is related with the encryption logic using the public exponent, however, I am not clear why it runs for only 16 iterations for the public exponent of 0x10001.

`LongElement s = paddedMsg;

	for (int i = 0; i < 16; i++) {
		s = s.mul(s);
		s = new LongIntegerModGadget(s, modulus, false).getRemainder();
	}
	s = s.mul(paddedMsg);
	s = new LongIntegerModGadget(s, modulus, true).getRemainder();`
  1. RSA key length is given as input to the gadget, shouldn't it have any effect on the public exponent?

Thank you very much.

A Trivial Issue: setWireValue(Wire w, long v)

public void setWireValue(Wire wire, long v) {
	setWireValue(wire, new BigInteger(v + ""));
}

For the above method, I found a trivial issue when I occasionally gave a "negative" v.
In this case, "circuitName.in" will have negative signs shown, and the libsnark interface cannot understand negative signs correctly. The prover will fail to create proof.

A temporary fix is as following:

public void setWireValue(Wire wire, int v) {
	setWireValue(wire, v & 0xffffffffL);
}
	
public void setWireValue (Wire wire, Long v) {
	setWireValue(wire, new BigInteger(Long.toUnsignedString(v)));
}

Change the curve

Hi akosba,
Is it still correct if I implement another curve in libsnark and use the same .arith and .in file directly as my input? I tried using the MNT4753 for libsnark which is a 768bit-curve but the constraint system doesn't satisfy itself. (assertion in CircuitReader.cpp, some assigned value changes because the field changes) I wonder whether this library can only use a 254-bit curve as its backend now?

But the way I used the implementation from coda, I think the curve has the same api as other curves in libsnark.
https://github.com/CodaProtocol/gpu-groth16-prover-3x

HELP: how to implement a solution in practice?

Hello, I would like to implement a zk-SNARKs scenario using jsnark but I can't figure out if it is indeed possible and how to approach the implementation in practice.

This library seems too technical for me at the moment. I would really appreciate it if there was anyone able to tell me if the following is possible and how to approach the implementation problem in practice, meaning how can I reach a point in which a prover can actually produce a proof file and then a verifier can simply take that file and verify it.

I would like to implement a scenario in which a prover P wants to prove the knowledge of the decrypted version of a file to a verifier V using zk-SNARKs. (The set-up phase to produce the proving and verification keys is done by a trusted third party of course.)

In this scenario there is a file f and its encrypted version is fE = Enc(f, k). Here Enc is a strong symmetric encryption algorithm such as AES and k is the key used to encrypt the file f.

The hash of the file f is Hf = SHA256(f)

In this scenario, I want the prover to be able to prove that:
SHA256(Dec(fE, k)) == Hf AND SHA256(k) == Hk
where obviously Dec( fE, k ) will produce the original file f.

The prover P will send to the verifier V the following elements, and V will be then able to verify the proof:

  • the proof itself just produced by P
  • the encrypted file fE
  • the hash of the file Hf
  • the hash of the key Hk

If the verification output is true (the proof is valid) the verifier V will be sure of the following:

  • Hf is the hash of a file f and the encrypted version of this file is fE (note that V doesn't have/know the original file f)
  • Hk is the hash of the key k used to encrypt the file f to obtain fE

Many thanks to anyone who takes the time to read!

Can Prover Witness Wires serve as NIZKInputs in pinocchio?

Hi Ahmed,

Great project! Thanks a lot for such a contribution. Please excuse me that there might be a naive question.

I have look at the FieldDivision example and find the prover_witness_wire seems to be directed to output. I read your document and am thinking any output will be public to the verifier. As a result, will the prover_witness_wire in that example become public?

If the prover_witness_wire in that example is public, is it possible to make a prover_witness_wire as a secret one, like NIZKInput does in Pinocchio? For example, a prover has ten numbers, and she only would like to convince the verifier their average instead of leaking these numbers. Will prover_witness_wires work in this scenario?

`make` fails for missing includes

When I follow the README, ./prepare-depends.sh runs fine. After that,

make yields

g++ -o src/interface/run_libsnark.o   src/interface/run_libsnark.cpp -c -MMD -std=c++11 -Wall -Wextra -Wno-unused-parameter -Wno-comment -Wfatal-errors -O2 -march=native -mtune=native -DUSE_ASM  -DCURVE_BN128 -Idepinst/include -Isrc -DBN_SUPPORT_SNARK -fPIC
In file included from src/common/data_structures/sparse_vector.hpp:77:0,
                 from src/common/data_structures/accumulation_vector.hpp:15,
                 from src/zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark.hpp:52,
                 from src/zk_proof_systems/ppzksnark/r1cs_ppzksnark/examples/run_r1cs_ppzksnark.tcc:18,
                 from src/zk_proof_systems/ppzksnark/r1cs_ppzksnark/examples/run_r1cs_ppzksnark.hpp:33,
                 from src/interface/../interface/CircuitReader.hpp:10,
                 from src/interface/run_libsnark.cpp:7:
src/common/data_structures/sparse_vector.tcc: In constructor �libsnark::sparse_vector<T>::sparse_vector(std::vector<T>&&)�:
src/common/data_structures/sparse_vector.tcc:26:10: error: �iota� is not a member of �std�
     std::iota(indices.begin(), indices.end(), 0);
          ^~~~
compilation terminated due to -Wfatal-errors.
Makefile:230: recipe for target 'src/interface/run_libsnark.o' failed
make: *** [src/interface/run_libsnark.o] Error 1

SHA 256 gadget's output wires have negative id

Hi Ahmed @akosba

I was trying to write a verification circuit using SHA256 gadget using an assert operation.
However, assert operation complains that the output wires of SHA256 have negative ids.

When I debugged, I found that the negative ids for the output wires of SHA256 gadget are injected within the 'trimBits' method, which is first invoked at line 158 of SHA256Gadget.java class.

This is because trimBits method returns a VariableWire without an id. Could you please let me know if this is the expected behavior?

Thank you.

The verification result for SimpleCircuitGenerator is always "PASS"

$ java -cp bin examples.generators.SimpleCircuitGenerator

on the original code produces these two files and the following result.

# simple_example.arith
total 12
input 0                  # The one-input wire.
const-mul-0 in 1 <0> out 1 <1>
input 2
input 3
input 4
input 5
mul in 2 <2 3> out 1 <6>
add in 2 <4 5> out 1 <7>
const-mul-5 in 1 <0> out 1 <8>
add in 2 <6 8> out 1 <9>
const-mul-6 in 1 <7> out 1 <10>
mul in 2 <9 10> out 1 <11>
output 11
# simple_example.in
0 1
2 1
3 2
4 3
5 4
Running Circuit Generator for < simple_example >
Circuit Generation Done for < simple_example >
     Total Number of Constraints :  2

Running Circuit Evaluator for < simple_example >
    [output] Value of Wire # 11 :: 294
Circuit Evaluation Done for < simple_example >



-----------------------------------RUNNING LIBSNARK -----------------------------------------
Reset time counters for profiling
(enter) Parsing and Evaluating the circuit  [             ] (0.0011s x1.00 from start)
     Evaluation Done in 0.000002 seconds
(leave) Parsing and Evaluating the circuit  [0.0002s x0.98] (0.0013s x1.00 from start)
Translating Constraints ...
    Constraint translation done
    Memory usage for constraint translation: 0 MB
Assignment of values done ..

Printing output assignment::
[output] Value of Wire # 11 :: 294

...

========================================================================
R1CS ppzkSNARK Verifier
========================================================================
* The verification result is: PASS

But when I intentionally change the contents of the input or the circuit file,
the result does not change.

For example, I tried to run libsnark with the following setup by manually changing the files.

# simple_example.arith
total 12
input 0                  # The one-input wire.
const-mul-0 in 1 <0> out 1 <1>
input 2
input 3
input 4
input 5
mul in 2 <3 2> out 1 <6>
add in 2 <3 2> out 1 <7>
const-mul-5 in 1 <0> out 1 <8>
add in 2 <3 2> out 1 <9>
const-mul-6 in 1 <7> out 1 <10>
mul in 2 <3 2> out 1 <11>
output 11
# simple_example.in
0 10
2 10
3 10
4 10
5 10
6 10

and I get this result.

Running Circuit Generator for < simple_example >
Circuit Generation Done for < simple_example >
     Total Number of Constraints :  2

Running Circuit Evaluator for < simple_example >
    [output] Value of Wire # 11 :: 294
Circuit Evaluation Done for < simple_example >



-----------------------------------RUNNING LIBSNARK -----------------------------------------
Reset time counters for profiling
(enter) Parsing and Evaluating the circuit  [             ] (0.0017s x0.67 from start)
     Evaluation Done in 0.000002 seconds
(leave) Parsing and Evaluating the circuit  [0.0002s x0.99] (0.0019s x0.70 from start)
Translating Constraints ...
    Constraint translation done
    Memory usage for constraint translation: 0 MB
Assignment of values done ..

Printing output assignment::
[output] Value of Wire # 11 :: 256

...

========================================================================
R1CS ppzkSNARK Verifier
========================================================================
* The verification result is: PASS

I've tried many different variations, but always get the same result.

How to recover circuit output from two files

I know that jsnark uses prepFiles() to generate .arith and .in files, but how can verifiers recover the circuit outputs from these two files?
For example, a prover generates a rsa circuit, uses pubkey to encrypt a plaintext and provides two files.
A verifier can easily use runLibsnark() for verification, but how can he get the pubkey value and cipherText from the two files?

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.