Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to recover circuit output from two files #26

Open
stark1092 opened this issue Mar 4, 2021 · 3 comments
Open

How to recover circuit output from two files #26

stark1092 opened this issue Mar 4, 2021 · 3 comments

Comments

@stark1092
Copy link

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?

@stark1092 stark1092 reopened this Mar 4, 2021
@akosba
Copy link
Owner

akosba commented Mar 4, 2021

Hello,

A verifier can easily use runLibsnark() for verification

First, please note that runLibsnark() is not related to the verifier only. This method runs the jsnark-libsnark interface, which reads the files and computes the values of all variables, including the output variables, then calls libsnark::run_r1cs_ppzksnark or libsnark::run_r1cs_gg_ppzksnark  which run all the three algorithms: key generation, proving and verification algorithms that are provided by libsnark. This all happens in a single call (just for demonstration and performance measurement purposes). 
In practice, these algorithms will have to be separated, because key generation, proving and verification will be done at different times by different parties. The separation is not provided in this version of jsnark.

With respect to the outputs and all other intermediate variables, they are not written to a file. They are computed during execution in two places:

  • In jsnark itself when the circuit is evaluated.
  • They are computed internally in the jsnark-libsnark interface when calling run_libsnark(). This is done in the CircuitReader class, after which the assignment of all variables will be ready. 

If you would like to generate a file with the output values, a method can be added to jsnark's CircuitEvaluator class.

public void writeOutputFile() {
		try {
			LinkedHashMap<Instruction, Instruction> evalSequence = circuitGenerator.getEvaluationQueue();

			PrintWriter printWriter = new PrintWriter(circuitGenerator.getName() + ".out");
			for (Instruction e : evalSequence.keySet()) {
				if (e instanceof WireLabelInstruction) {
					WireLabelInstruction inst = (WireLabelInstruction) e;
					if (inst.getType() == LabelType.output) {
						int id = ((WireLabelInstruction) e).getWire().getWireId();
						printWriter.println(id + " " + valueAssignment[id].toString(16) + (inst.getDesc().length() > 0 ? (" \t\t# " + inst.getDesc()) : ""));
					}
				}
			}
			printWriter.close();

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

This will also print any available labels for the output wires beside its value. The above will require adding another method in the WireLabelInstruction class

public String getDesc() {
    return desc;
}

And finally add a call to circuitEvaluator.writeOutputFile(); to prepFiles() of the CircuitGenerator class.

The output values can also be provided to the verifier through other means. For example, the prover could call standard cryptographic libraries and send their outputs in the scenario you mentioned, i.e., the prover does not have to get that from the circuit. (We will need to be sure though that the circuit implements the same algorithm and to format the output properly).

Note that in order to use the above in a meaningful scenario, I think that the separation I referred to above might need to be implemented. For example, this could be done by adding support for a method, e.g., runLibsnarkVerifier, that will call a libsnark executable that takes public* input and output values and a verification key.
(* The .in file includes both public and prover private inputs. The verifier will only need the public inputs.)

@stark1092
Copy link
Author

@akosba Thanks for your reply! This is very helpful, let me understand more about jsnark.
So if I want a prover to provide the public input(public key) and public output(proof value, cipherText) of a encryption process, and a verifier to verify these, I need to generate corresponding parameters and call libsnark?
I need to use jsnark to write circuit and generate files(.arith & .in) first, and then split prove/verify in the step of calling libsnark?

@thomaslavaur
Copy link

Has anyone already implemented a runLibsnarkVerifier or runLibsnarkProver to avoid the execution of the three algorithms ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants