def generate_proof(self, project_dir: str, contract: str, function: str, priv_values: List, in_vals: List, out_vals: List[Union[int, CipherValue]]) -> List[int]: """ Generate a NIZK-proof using the provided circuit for the given arguments. Note: circuit arguments must be in the same order as they are declared inside the circuit. (i.e. in execution order) :param project_dir: directory where the manifest and the prover keys are located :param contract: contract of which the function which requires verification is part of :param function: the contract member function for which a proof needs to be generated :param priv_values: private/auxiliary circuit inputs in correct order :param in_vals: public circuit inputs in correct order :param out_vals: public circuit outputs in correct order :raise ProofGenerationError: if proof generation fails :return: the proof, serialized into an uint256 array """ for i in range(len(priv_values)): arg = priv_values[i] assert not isinstance(arg, Value) or isinstance(arg, (RandomnessValue, AddressValue)) if isinstance(arg, AddressValue): priv_values[i] = int.from_bytes(arg.val, byteorder='big') zk_print(f'Generating proof for {contract}.{function}') zk_print(f'[priv: {Value.collection_to_string(priv_values)}] ' f'[in: {Value.collection_to_string(in_vals)}] [out: {Value.collection_to_string(out_vals)}]', verbosity_level=2) priv_values, in_vals, out_vals = Value.unwrap_values(Value.flatten(priv_values)), Value.unwrap_values(in_vals), Value.unwrap_values(out_vals) # Check for overflows for arg in priv_values + in_vals + out_vals: assert int(arg) < bn128_scalar_field, 'argument overflow' with time_measure(f'generate_proof', True): verify_dir = cfg.get_circuit_output_dir_name(cfg.get_verification_contract_name(contract, function)) return self._generate_proof(os.path.join(project_dir, verify_dir), priv_values, in_vals, out_vals)
def get_verification_contract_names(code_or_ast) -> List[str]: if isinstance(code_or_ast, str): ast = get_processed_ast(code_or_ast) else: ast = code_or_ast if not isinstance(ast, SourceUnit): raise ZkayCompilerError('Invalid AST (no source unit at root)') vc_names = [] for contract in ast.contracts: cname = contract.idf.name fcts = [ fct for fct in contract.function_definitions + contract.constructor_definitions if fct.requires_verification_when_external and fct.has_side_effects ] vc_names += [ cfg.get_verification_contract_name(cname, fct.name) for fct in fcts ] return vc_names
def include_verification_contracts(self, su: SourceUnit, c: ContractDefinition) -> List[StateVariableDeclaration]: """ Import all verification contracts for 'c' into 'su' and create state variable declarations for all of them + the pki contract. :param su: [SIDE EFFECT] source unit into which contracts should be imported :param c: contract for which verification contracts should be imported :return: list of all constant state variable declarations for the pki contract + all the verification contracts """ contract_var_decls = [] for crypto_params in c.used_crypto_backends: contract_name = cfg.get_pki_contract_name(crypto_params) contract_var_decls.append(self.create_contract_variable(contract_name)) for f in c.constructor_definitions + c.function_definitions: if f.requires_verification_when_external and f.has_side_effects: name = cfg.get_verification_contract_name(c.idf.name, f.name) self.import_contract(name, su, self.circuits[f]) contract_var_decls.append(self.create_contract_variable(name)) return contract_var_decls