def compile_and_run_with_circuit_builder(working_dir, class_name, java_file_name, args: List[str]): # Compile the circuit java file run_command(['javac', '-cp', f'{circuit_builder_jar}', java_file_name], cwd=working_dir) # Run jsnark to generate the circuit return run_command([ 'java', '-Xms4096m', '-Xmx16384m', '-cp', f'{circuit_builder_jar}:{working_dir}', class_name, *args ], cwd=working_dir, allow_verbose=True)
def generate_keys(input_dir: str, output_dir: str, proving_scheme: str): """ Generate prover and verification keys for the circuit in output_dir with the specified proving_scheme. :param input_dir: path to directory where the circuit.arith and .in files are located :param output_dir: path to the directory where the keys should be saved :param proving_scheme: name of the proving scheme to use :raise SubprocessError: if key generation fails :raise KeyError: if proving scheme name is invalid """ run_command([ libsnark_runner, 'keygen', input_dir, output_dir, str(proving_scheme_map[proving_scheme]) ], allow_verbose=True)
def _gen_keypair(rnd: bytes): keys, _ = run_command([ 'java', '-Xms4096m', '-Xmx16384m', '-cp', f'{circuit_builder_jar}', 'zkay.ZkayECDHGenerator', rnd.hex() ]) keys = keys.splitlines()[-2:] return int(keys[0], 16), int(keys[1], 16)
def generate_proof(key_dir: str, input_dir: str, output_path: str, proving_scheme: str): """ Generate a NIZK-proof for the circuit and input files in output_dir. :param key_dir: directory where proving.key and verifying.key.bin are located :param input_dir: directory where circuit.arith and circuit.in for this circuit are located. :param output_path: output path for the generated proof file :param proving_scheme: name of the proving scheme to use :raise SubprocessError: if proof generation fails :raise KeyError: if proving scheme name is invalid """ run_command([ libsnark_runner, 'proofgen', input_dir, output_path, key_dir, str(proving_scheme_map[proving_scheme]), str(int(cfg.libsnark_check_verify_locally_during_proof_generation)) ], allow_verbose=True)
def _ecdh_sha256(other_pk: int, my_sk: int): ret, _ = run_command([ 'java', '-Xms4096m', '-Xmx16384m', '-cp', f'{circuit_builder_jar}', 'zkay.ZkayECDHGenerator', hex(my_sk)[2:], hex(other_pk)[2:] ]) key = ret.splitlines()[-1] return int(key, 16).to_bytes(16, byteorder='big')
def prepare_proof(circuit_dir: str, output_dir: str, serialized_args: List[int]): """ Generate a libsnark circuit input file by evaluating the circuit in jsnark using the provided input values. :param circuit_dir: directory where the compiled circuit is located :param output_dir: directory, where to store the jsnark output files :param serialized_args: public inputs, public outputs and private inputs in the order in which they are defined in the circuit :raise SubprocessError: if circuit evaluation fails """ serialized_arg_str = [format(arg, 'x') for arg in serialized_args] # Run jsnark to evaluate the circuit and compute prover inputs run_command([ 'java', '-Xms4096m', '-Xmx16384m', '-cp', f'{circuit_builder_jar}:{circuit_dir}', cfg.jsnark_circuit_classname, 'prove', *serialized_arg_str ], cwd=output_dir, allow_verbose=True)
def _enc(self, plain: int, my_sk: int, target_pk: int) -> Tuple[List[int], None]: # Compute shared key key = self._ecdh_sha256(target_pk, my_sk) plain_bytes = plain.to_bytes(32, byteorder='big') # Call java implementation iv = secrets.token_bytes(16) iv_cipher, _ = run_command(['java', '-Xms4096m', '-Xmx16384m', '-cp', f'{circuit_builder_jar}', 'zkay.ChaskeyLtsCbc', 'enc', key.hex(), iv.hex(), plain_bytes.hex()]) iv_cipher = iv + int(iv_cipher.splitlines()[-1], 16).to_bytes(32, byteorder='big') return self.pack_byte_array(iv_cipher, self.params.cipher_chunk_size), None
def compile_circuit(circuit_dir: str, javacode: str): """ Compile the given circuit java code and then compile the circuit which it describes using jsnark. :param circuit_dir: output directory :param javacode: circuit code (java class which uses the custom jsnark wrapper API) :raise SubprocessError: if compilation fails """ jfile = os.path.join(circuit_dir, cfg.jsnark_circuit_classname + ".java") with open(jfile, 'w') as f: f.write(javacode) # Compile the circuit java file run_command(['javac', '-cp', f'{circuit_builder_jar}', jfile], cwd=circuit_dir) # Run jsnark to generate the circuit run_command([ 'java', '-Xms4096m', '-Xmx16384m', '-cp', f'{circuit_builder_jar}:{circuit_dir}', cfg.jsnark_circuit_classname, 'compile' ], cwd=circuit_dir, allow_verbose=True)
def _dec(self, cipher: Tuple[int, ...], my_sk: Any) -> Tuple[int, None]: # Extract sender address from cipher metadata and request corresponding public key sender_pk = cipher[-1] cipher = cipher[:-1] assert len(cipher) == self.params.cipher_payload_len # Compute shared key key = self._ecdh_sha256(sender_pk, my_sk) # Call java implementation iv_cipher = self.unpack_to_byte_array(cipher, self.params.cipher_chunk_size, self.params.cipher_bytes_payload) iv, cipher_bytes = iv_cipher[:16], iv_cipher[16:] plain, _ = run_command(['java', '-Xms4096m', '-Xmx16384m', '-cp', f'{circuit_builder_jar}', 'zkay.ChaskeyLtsCbc', 'dec', key.hex(), iv.hex(), cipher_bytes.hex()]) plain = int(plain.splitlines()[-1], 16) return plain, None
def test_echo(self): output, error = run_command(['echo', 'abc']) self.assertEqual(output, "abc") self.assertEqual(error, "")
def test_sleep(self): output, error = run_command(['bash', '-c', 'sleep 0.5; echo "abc"']) self.assertEqual(output, "abc") self.assertEqual(error, "")
def test_error(self): with self.assertRaises(SubprocessError): run_command(['ls', '-error'])