Skip to content

Commit

Permalink
cli
Browse files Browse the repository at this point in the history
  • Loading branch information
feltroidprime committed Dec 9, 2024
1 parent fd90444 commit 57b75b7
Show file tree
Hide file tree
Showing 14 changed files with 71 additions and 70 deletions.
3 changes: 3 additions & 0 deletions hydra/garaga/definitions.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,14 @@

class ProofSystem(Enum):
Groth16 = "groth16"
UltraKeccakHonk = "ultra_keccak_honk"

@property
def supported_curves(self) -> set[int]:
if self == ProofSystem.Groth16:
return {BN254_ID, BLS12_381_ID}
if self == ProofSystem.UltraKeccakHonk:
return {BN254_ID}
return set()


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ def build_input(self) -> list[PyFelt]:
temp_instance = struct_info(name, None)
total_elements += len(temp_instance)

print(f"Total elements: {total_elements}")
# print(f"Total elements: {total_elements}")
return [self.field.random() for _ in range(total_elements)]

def _run_circuit_inner(self, input: list[PyFelt]) -> ModuloCircuit:
Expand Down
36 changes: 21 additions & 15 deletions hydra/garaga/starknet/cli/gen.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
from garaga.starknet.cli.utils import complete_proof_system
from garaga.starknet.groth16_contract_generator.generator import (
ECIP_OPS_CLASS_HASH,
Groth16VerifyingKey,
gen_groth16_verifier,
)
from garaga.starknet.honk_contract_generator.generator_honk import gen_honk_verifier


def gen(
Expand All @@ -23,7 +23,7 @@ def gen(
vk: Annotated[
Path,
typer.Option(
help="Path to the verification key JSON file",
help="Path to the verification key file. Expects a JSON for groth16, binary format for Honk.",
file_okay=True,
dir_okay=False,
exists=True,
Expand All @@ -43,11 +43,6 @@ def gen(
Generate a Cairo verifier for a given proof system.
Automatically detects the curve from the verification key.
"""
verifying_key = Groth16VerifyingKey.from_json(vk)
print(
f"[bold cyan]Detected curve: [bold yellow]{verifying_key.curve_id}[/bold yellow][/bold cyan]"
)

cwd = Path.cwd()
with Progress(
SpinnerColumn(),
Expand All @@ -58,13 +53,24 @@ def gen(
f"[bold cyan]Generating Smart Contract project for [bold yellow]{system}[/bold yellow] using [bold yellow]{Path(vk).name}[/bold yellow]...[/bold cyan]",
total=None,
)
gen_groth16_verifier(
vk=verifying_key,
output_folder_path=cwd,
output_folder_name=project_name,
ecip_class_hash=ECIP_OPS_CLASS_HASH,
cli_mode=True,
)
match system:
case ProofSystem.Groth16:
gen_groth16_verifier(
vk=vk,
output_folder_path=cwd,
output_folder_name=project_name,
ecip_class_hash=ECIP_OPS_CLASS_HASH,
cli_mode=True,
)
case ProofSystem.UltraKeccakHonk:
gen_honk_verifier(
vk=vk,
output_folder_path=cwd,
output_folder_name=project_name,
cli_mode=True,
)
case _:
raise ValueError(f"Unsupported proof system: {system}")

print("[bold green]Done![/bold green]")
print("[bold cyan]Smart Contract project created:[/bold cyan]")
Expand All @@ -82,5 +88,5 @@ def generate_tree(path: Path, tree: Tree) -> None:
print(root)

print(
"[bold]You can now modify the [bold yellow]groth16_verifier.cairo[/bold yellow] file to adapt the verifier to your use case.[/bold]"
f"[bold]You can now test the main endpoint of the verifier using a proof and `garaga calldata` command.[/bold]"
)
50 changes: 28 additions & 22 deletions hydra/garaga/starknet/cli/verify.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@
Groth16VerifyingKey,
find_item_from_key_patterns,
)
from garaga.starknet.honk_contract_generator.calldata import (
HonkProof,
HonkVk,
get_ultra_keccak_honk_calldata_from_vk_and_proof,
)

app = typer.Typer()

Expand Down Expand Up @@ -109,19 +114,15 @@ def verify_onchain(
] = "eth",
):
"""Invoke a SNARK verifier on Starknet given a contract address, a proof and a verification key."""
vk_obj = Groth16VerifyingKey.from_json(vk)
proof_obj = Groth16Proof.from_json(proof, public_inputs)

load_dotenv(env_file)
account = load_account(network)

contract = get_contract_iff_exists(account, to_int(contract_address))
if endpoint == "":
endpoint = f"verify_{system.value}_proof_{vk_obj.curve_id.name.lower()}"

try:
function_call: ContractFunction = find_item_from_key_patterns(
contract.functions, [endpoint]
contract.functions, ["verify"]
)
except ValueError:
rich.print(
Expand All @@ -134,10 +135,8 @@ def verify_onchain(
if public_inputs == "":
public_inputs = None

calldata = groth16_calldata_from_vk_and_proof(
vk=vk_obj,
proof=proof_obj,
)
calldata = get_calldata_generic(system, vk, proof, public_inputs)

if "eth" in fee.lower():
prepare_invoke = PreparedFunctionInvokeV1(
to_addr=function_call.contract_data.address,
Expand Down Expand Up @@ -176,6 +175,22 @@ class CalldataFormat(str, Enum):
array = "array"


def get_calldata_generic(
system: ProofSystem, vk: Path, proof: Path, public_inputs: Path | None
) -> list[int]:
match system:
case ProofSystem.Groth16:
vk_obj = Groth16VerifyingKey.from_json(vk)
proof_obj = Groth16Proof.from_json(proof, public_inputs)
return groth16_calldata_from_vk_and_proof(vk, proof)
case ProofSystem.UltraKeccakHonk:
vk_obj = HonkVk.from_bytes(open(vk, "rb").read())
proof_obj = HonkProof.from_bytes(open(proof, "rb").read())
return get_ultra_keccak_honk_calldata_from_vk_and_proof(vk_obj, proof_obj)
case _:
raise ValueError(f"Proof system {system} not supported")


def calldata(
system: Annotated[
ProofSystem,
Expand All @@ -184,7 +199,7 @@ def calldata(
vk: Annotated[
Path,
typer.Option(
help="Path to the verification key JSON file",
help="Path to the verification key file",
file_okay=True,
dir_okay=False,
exists=True,
Expand All @@ -194,7 +209,7 @@ def calldata(
proof: Annotated[
Path,
typer.Option(
help="Path to the proof JSON file",
help="Path to the proof file",
file_okay=True,
dir_okay=False,
exists=True,
Expand All @@ -204,7 +219,7 @@ def calldata(
public_inputs: Annotated[
Path,
typer.Option(
help="Path to the public inputs JSON file",
help="Path to the public inputs file. Optional, only used for Groth16 when pub inputs are not in the json proof (ex: SnarkJS)",
file_okay=True,
dir_okay=False,
exists=True,
Expand All @@ -222,16 +237,7 @@ def calldata(
):
"""Generate Starknet verifier calldata given a proof and a verification key."""

if system == ProofSystem.Groth16:
vk_obj = Groth16VerifyingKey.from_json(vk)
proof_obj = Groth16Proof.from_json(proof, public_inputs)

calldata = groth16_calldata_from_vk_and_proof(
vk=vk_obj,
proof=proof_obj,
)
else:
raise ValueError(f"Proof system {system} not supported")
calldata = get_calldata_generic(system, vk, proof, public_inputs)

if format == CalldataFormat.starkli:
print(" ".join([str(x) for x in calldata]))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ def get_scarb_toml_file(package_name: str, cli_mode: bool):
sierra-replace-ids = false
[dev-dependencies]
cairo_test = "2.8.4"
cairo_test = "2.9.1"
[[target.starknet-contract]]
casm = true
Expand Down
16 changes: 5 additions & 11 deletions hydra/garaga/starknet/honk_contract_generator/generator_honk.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,7 @@
from garaga.precompiled_circuits.honk import G2_POINT_KZG_1, G2_POINT_KZG_2, HonkVk
from garaga.precompiled_circuits.multi_miller_loop import precompute_lines
from garaga.starknet.cli.utils import create_directory
from garaga.starknet.groth16_contract_generator.generator import (
ECIP_OPS_CLASS_HASH,
get_scarb_toml_file,
)
from garaga.starknet.groth16_contract_generator.generator import get_scarb_toml_file


def precompute_lines_honk() -> StructArray:
Expand Down Expand Up @@ -106,7 +103,6 @@ def gen_honk_verifier(
vk: str | Path | HonkVk | bytes,
output_folder_path: str,
output_folder_name: str,
ecip_class_hash: int = ECIP_OPS_CLASS_HASH,
cli_mode: bool = False,
) -> str:
if isinstance(vk, (Path, str)):
Expand Down Expand Up @@ -152,7 +148,7 @@ def gen_honk_verifier(
#[starknet::interface]
trait IUltraKeccakHonkVerifier<TContractState> {{
fn verify_ultra_keccak_honk(
fn verify_ultra_keccak_honk_proof(
self: @TContractState,
full_proof_with_hints: Span<felt252>,
) -> Option<Span<u256>>;
Expand All @@ -174,8 +170,6 @@ def gen_honk_verifier(
use core::num::traits::Zero;
use core::poseidon::hades_permutation;
const ECIP_OPS_CLASS_HASH: felt252 = {hex(ecip_class_hash)};
#[storage]
struct Storage {{}}
Expand All @@ -189,7 +183,7 @@ def gen_honk_verifier(
#[abi(embed_v0)]
impl IUltraKeccakHonkVerifier of super::IUltraKeccakHonkVerifier<ContractState> {{
fn verify_ultra_keccak_honk(
fn verify_ultra_keccak_honk_proof(
self: @ContractState,
full_proof_with_hints: Span<felt252>,
) -> Option<Span<u256>> {{
Expand Down Expand Up @@ -431,7 +425,7 @@ def gen_honk_verifier(
create_directory(src_dir)

with open(os.path.join(output_folder_path, ".tools-versions"), "w") as f:
f.write("scarb 2.8.4\n")
f.write("scarb 2.9.1\n")

with open(os.path.join(src_dir, "honk_verifier_constants.cairo"), "w") as f:
f.write(constants_code)
Expand Down Expand Up @@ -469,4 +463,4 @@ def gen_honk_verifier(
"noir_ultra_keccak_honk_example" # '_curve_id' is appended in the end.
)

gen_honk_verifier(VK_PATH, CONTRACTS_FOLDER, FOLDER_NAME, ECIP_OPS_CLASS_HASH)
gen_honk_verifier(VK_PATH, CONTRACTS_FOLDER, FOLDER_NAME)
2 changes: 1 addition & 1 deletion src/contracts/groth16_example_bls12_381/Scarb.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ starknet = "2.9.1"
sierra-replace-ids = false

[dev-dependencies]
cairo_test = "2.8.4"
cairo_test = "2.9.1"

[[target.starknet-contract]]
casm = true
Expand Down
2 changes: 1 addition & 1 deletion src/contracts/groth16_example_bn254/Scarb.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ starknet = "2.9.1"
sierra-replace-ids = false

[dev-dependencies]
cairo_test = "2.8.4"
cairo_test = "2.9.1"

[[target.starknet-contract]]
casm = true
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
scarb 2.8.4
scarb 2.9.1
2 changes: 1 addition & 1 deletion src/contracts/noir_ultra_keccak_honk_example/Scarb.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ starknet = "2.9.1"
sierra-replace-ids = false

[dev-dependencies]
cairo_test = "2.8.4"
cairo_test = "2.9.1"

[[target.starknet-contract]]
casm = true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use super::honk_verifier_circuits::{

#[starknet::interface]
trait IUltraKeccakHonkVerifier<TContractState> {
fn verify_ultra_keccak_honk(
fn verify_ultra_keccak_honk_proof(
self: @TContractState, full_proof_with_hints: Span<felt252>,
) -> Option<Span<u256>>;
}
Expand Down Expand Up @@ -37,9 +37,6 @@ mod UltraKeccakHonkVerifier {
use core::num::traits::Zero;
use core::poseidon::hades_permutation;

const ECIP_OPS_CLASS_HASH: felt252 =
0xc4b7aa28a27b5fb8d7d43928b2a3ee960cf5b4e06cb9ae1ee3f102400b1700;

#[storage]
struct Storage {}

Expand All @@ -53,7 +50,7 @@ mod UltraKeccakHonkVerifier {

#[abi(embed_v0)]
impl IUltraKeccakHonkVerifier of super::IUltraKeccakHonkVerifier<ContractState> {
fn verify_ultra_keccak_honk(
fn verify_ultra_keccak_honk_proof(
self: @ContractState, full_proof_with_hints: Span<felt252>,
) -> Option<Span<u256>> {
// DO NOT EDIT THIS FUNCTION UNLESS YOU KNOW WHAT YOU ARE DOING.
Expand Down
2 changes: 1 addition & 1 deletion src/contracts/risc0_verifier_bn254/Scarb.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ starknet = "2.9.1"
sierra-replace-ids = false

[dev-dependencies]
cairo_test = "2.8.4"
cairo_test = "2.9.1"

[[target.starknet-contract]]
casm = true
Expand Down
6 changes: 3 additions & 3 deletions tests/contracts_e2e/e2e_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ async def test_groth16_contracts(account_devnet: BaseAccount, contract_info: dic
print(f"Deployed contract: {contract.functions}")

function_call: ContractFunction = find_item_from_key_patterns(
contract.functions, ["verify_groth16"]
contract.functions, ["verify"]
)

prepare_invoke = PreparedFunctionInvokeV3(
Expand Down Expand Up @@ -212,7 +212,7 @@ async def test_drand_contract(account_devnet: BaseAccount, contract_info: dict):
print(f"Deployed contract: {contract.functions}")

function_call: ContractFunction = find_item_from_key_patterns(
contract.functions, ["verify_round_and_get_randomness"]
contract.functions, ["verify"]
)

for drand_round in range(1, 5):
Expand Down Expand Up @@ -294,7 +294,7 @@ async def test_honk_contracts(account_devnet: BaseAccount, contract_info: dict):
print(f"Deployed contract: {contract.functions}")

function_call: ContractFunction = find_item_from_key_patterns(
contract.functions, ["verify_ultra_keccak_honk"]
contract.functions, ["verify"]
)

prepare_invoke = PreparedFunctionInvokeV3(
Expand Down
9 changes: 2 additions & 7 deletions tools/noir/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,11 @@ EOF
reset


# nargo version : nargo version = 0.36.0
# noirc version = 0.36.0+801c71880ecf8386a26737a5d8bb5b4cb164b2ab
# (git version hash: 801c71880ecf8386a26737a5d8bb5b4cb164b2ab, is dirty: false)
# bb version : 0.58.0

BB_PATH="/home/felt/PycharmProjects/aztec2/aztec-packages/barretenberg/cpp/build/bin/bb"
BB_PATH="bb"


echo "nargo version : $(nargo --version)" # 0.36.0
echo "bb version : $($BB_PATH --version)" # 0.58.0
echo "bb version : $($BB_PATH --version)" # 0.61.0


run_noir_proof_basic() {
Expand Down

0 comments on commit 57b75b7

Please sign in to comment.