Skip to content

Commit

Permalink
Merge branch 'main' into g2
Browse files Browse the repository at this point in the history
  • Loading branch information
feltroidprime authored Dec 6, 2024
2 parents b896b6c + b44d00d commit 4815075
Show file tree
Hide file tree
Showing 46 changed files with 17,445 additions and 36,164 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/maturin.yml
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ jobs:
strategy:
matrix:
platform:
- runner: macos-12
- runner: macos-14
target: x86_64
- runner: macos-14
target: aarch64
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,14 +122,14 @@ garaga
Once your verifying key is ready, you can use the following command : 

```
garaga gen --system groth16 --vk vk.json
garaga gen --system groth16 --vk vk.json
```

You should see an output like this :

```bash
(venv) :~/garaga-flow garaga gen --system groth16 --vk vk_bls.json
Please enter the name of your project. Press enter for default name. [my_project]:
(venv) :~/garaga-flow garaga gen --system groth16 --vk vk_bls.json
Please enter the name of your project. Press enter for default name. [my_project]:
Detected curve: CurveID.BLS12_381
⠧ Generating Smart Contract project for ProofSystem.Groth16 using vk_bls.json...
Done!
Expand Down Expand Up @@ -301,41 +301,41 @@ MAINNET_ACCOUNT_ADDRESS=0x4
```
{% endcode %}

Then, you can run the command `garaga declare-project`, which will build the contract and declare it to Starknet. If the class hash is already deployed, it will return it as well. Declaring the contract involves sending all its bytecode and it is quite an expensive operation. Make sure you dapp is properly tested before!
Then, you can run the command `garaga declare`, which will build the contract and declare it to Starknet. If the class hash is already deployed, it will return it as well. Declaring the contract involves sending all its bytecode and it is quite an expensive operation. Make sure you dapp is properly tested before!

```bash
Usage: garaga declare-project [OPTIONS]
Declare your smart contract to Starknet. Obtain its class hash and a explorer link.
Usage: garaga declare [OPTIONS]

Declare your smart contract to Starknet. Obtain its class hash and a explorer link.

╭─ Options ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --project-path DIRECTORY Path to the Cairo project holding the Scarb.toml file to declare
│ [default: /home/felt/PycharmProjects/garaga-flow/my_project/] │
│ [default: /home/felt/garaga-flow/my_project/] │
│ --env-file FILE Path to the environment file │
│ [default: /home/felt/PycharmProjects/garaga-flow/my_project/.secrets] │
│ [default: /home/felt/garaga-flow/my_project/.secrets] │
│ --network [sepolia|mainnet] Starknet network [default: sepolia] │
│ --fee TEXT Fee token type [eth, strk] [default: eth] │
│ --help -h Show this message and exit. │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
```

```bash
garaga declare-project --project-path my-project/ --env-file .secrets --network sepolia --fee strk
garaga declare --project-path my_project/ --env-file .secrets --network sepolia --fee strk
```

This command will return the class hash, used in the next step.\
\
Finally, to deploy the contract, a use `garaga deploy-project` :
Finally, to deploy the contract, a use `garaga deploy` :

```bash
Usage: garaga deploy-project [OPTIONS]
Deploy an instance of a smart contract class hash to Starknet. Obtain its address, the available endpoints and a explorer link.
Usage: garaga deploy [OPTIONS]

Deploy an instance of a smart contract class hash to Starknet. Obtain its address, the available endpoints and a explorer link.

╭─ Options ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
* --class-hash TEXT Contract class hash to deploy. Can be decimal or hex string [default: None] [required] │
│ --env-file FILE Path to the environment file containing rpc, address, private_key │
│ [default: /home/felt/PycharmProjects/garaga-flow/my_project/.secrets] │
│ [default: /home/felt/garaga-flow/my_project/.secrets] │
│ --network [sepolia|mainnet] Starknet network [default: sepolia] │
│ --fee TEXT Fee token type [eth, strk] [default: strk] │
│ --help -h Show this message and exit. │
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ The Garaga CLI takes care of converting your proof to the correct calldata and c
To do this, use the garaga `verify-onchain` command. 

```bash
Usage: garaga verify-onchain [OPTIONS]
Invoke a SNARK verifier on Starknet given a contract address, a proof and a verification key.
Usage: garaga verify-onchain [OPTIONS]

Invoke a SNARK verifier on Starknet given a contract address, a proof and a verification key.

╭─ Options ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
* --system [groth16] Proof system [default: None] [required] │
* --contract-address TEXT Starknet contract address [default: None] [required] │
Expand Down Expand Up @@ -73,7 +73,7 @@ The command should look like this:

{% code overflow="wrap" %}
```
garaga verify-onchain --system groth16 --address 0x1234... --vk vk.json --proof proof.json --public-inputs public.json --env-file .secrets --network sepolia
garaga verify-onchain --system groth16 --contract-address 0x1234... --vk vk.json --proof proof.json --public-inputs public.json --env-file .secrets --network sepolia
```
{% endcode %}

Expand Down
14 changes: 9 additions & 5 deletions hydra/garaga/algebra.py
Original file line number Diff line number Diff line change
Expand Up @@ -1043,12 +1043,16 @@ def degrees_infos(self) -> dict[str, dict[str, int]]:
"b": self.b.degrees_infos(),
}

def validate_degrees(self, msm_size: int) -> bool:
def validate_degrees(self, msm_size: int, batched: bool = True) -> bool:
degrees = self.degrees_infos()
assert degrees["a"]["numerator"] <= msm_size + 1
assert degrees["a"]["denominator"] <= msm_size + 2
assert degrees["b"]["numerator"] <= msm_size + 2
assert degrees["b"]["denominator"] <= msm_size + 5
if batched:
extra = 2
else:
extra = 0
assert degrees["a"]["numerator"] <= msm_size + 1 + extra
assert degrees["a"]["denominator"] <= msm_size + 2 + extra
assert degrees["b"]["numerator"] <= msm_size + 2 + extra
assert degrees["b"]["denominator"] <= msm_size + 5 + extra
return True

def print_as_sage_poly(self, var: str = "x", as_hex: bool = False) -> str:
Expand Down
32 changes: 31 additions & 1 deletion hydra/garaga/definitions.py
Original file line number Diff line number Diff line change
Expand Up @@ -1227,5 +1227,35 @@ def replace_consecutive_zeros(lst):
return result


def recode_naf_bits(lst):
result = []
i = 0
while i < len(lst):
if i < len(lst) - 1 and lst[i] == 0 and (lst[i + 1] == 1 or lst[i + 1] == -1):
# "01" or "0-1"
if lst[i + 1] == 1:
result.append(3) # Replace "01" with 3
else:
result.append(4) # Replace "0-1" with 4
i += 2
elif i < len(lst) - 1 and (lst[i] == 1 or lst[i] == -1) and lst[i + 1] == 0:
# "10" or "-10"
if lst[i] == 1:
result.append(1) # Replace 10 with 6
else:
result.append(2) # Replace -10 with 7
i += 2
elif i < len(lst) - 1 and lst[i] == 0 and lst[i + 1] == 0:
result.append(0) # Replace consecutive zeros with 0
i += 2
else:
raise ValueError(f"Unexpected bit sequence at index {i}")
return result


if __name__ == "__main__":
pass
r = recode_naf_bits(jy00(6 * 0x44E992B44A6909F1 + 2)[2:])
print(r, len(r))

# bls = [int(x) for x in bin(0xD201000000010000)[2:]][2:]
# recode_naf_bits(bls)
26 changes: 26 additions & 0 deletions hydra/garaga/hints/ecip.py
Original file line number Diff line number Diff line change
Expand Up @@ -661,6 +661,32 @@ def print_ff(ff: FF):
return string


def n_points_from_n_coeffs(n_coeffs: int, batched: bool) -> int:
if batched:
extra = 4 * 2
else:
extra = 0

# n_coeffs = 10 + 4n_points => 4n_points = n_coeffs - 10
assert n_coeffs >= 10 + extra
assert (n_coeffs - 10 - extra) % 4 == 0
return (n_coeffs - 10 - extra) // 4


def n_coeffs_from_n_points(n_points: int, batched: bool) -> tuple[int, int, int, int]:
if batched:
extra = 2
else:
extra = 0

return (
1 + n_points + extra,
1 + n_points + 1 + extra,
1 + n_points + 1 + extra,
1 + n_points + 4 + extra,
)


if __name__ == "__main__":
import random

Expand Down
26 changes: 17 additions & 9 deletions hydra/garaga/hints/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ def fill_uint256(x: int, ids: object):


def padd_function_felt(
f: FunctionFelt, n: int, py_felt: bool = False
f: FunctionFelt, n: int, py_felt: bool = False, batched: bool = False
) -> tuple[list[int], list[int], list[int], list[int]]:
a_num = f.a.numerator.get_coeffs() if py_felt else f.a.numerator.get_value_coeffs()
a_den = (
Expand All @@ -298,15 +298,23 @@ def padd_function_felt(
b_den = (
f.b.denominator.get_coeffs() if py_felt else f.b.denominator.get_value_coeffs()
)
assert len(a_num) <= n + 1
assert len(a_den) <= n + 2
assert len(b_num) <= n + 2
assert len(b_den) <= n + 5
assert len(a_num) <= n + 1 + (
2 if batched else 0
), f"a_num has {len(a_num)} limbs, expected at most {n + 1 + (2 if batched else 0)}"
assert len(a_den) <= n + 2 + (
2 if batched else 0
), f"a_den has {len(a_den)} limbs, expected at most {n + 2 + (2 if batched else 0)}"
assert len(b_num) <= n + 2 + (
2 if batched else 0
), f"b_num has {len(b_num)} limbs, expected at most {n + 2 + (2 if batched else 0)}"
assert len(b_den) <= n + 5 + (
2 if batched else 0
), f"b_den has {len(b_den)} limbs, expected at most {n + 5 + (2 if batched else 0)}"
zero = [f.a.numerator.field.zero()] if py_felt else [0]
a_num = a_num + zero * (n + 1 - len(a_num))
a_den = a_den + zero * (n + 2 - len(a_den))
b_num = b_num + zero * (n + 2 - len(b_num))
b_den = b_den + zero * (n + 5 - len(b_den))
a_num = a_num + zero * (n + 1 + (2 if batched else 0) - len(a_num))
a_den = a_den + zero * (n + 2 + (2 if batched else 0) - len(a_den))
b_num = b_num + zero * (n + 2 + (2 if batched else 0) - len(b_num))
b_den = b_den + zero * (n + 5 + (2 if batched else 0) - len(b_den))
return (a_num, a_den, b_num, b_den)


Expand Down
4 changes: 2 additions & 2 deletions hydra/garaga/modulo_circuit_structs.py
Original file line number Diff line number Diff line change
Expand Up @@ -503,10 +503,10 @@ def struct_name(self) -> str:

@staticmethod
def from_FunctionFelt(
name: str, f: FunctionFelt, msm_size: int
name: str, f: FunctionFelt, msm_size: int, batched: bool = False
) -> "FunctionFeltCircuit":
_a_num, _a_den, _b_num, _b_den = io.padd_function_felt(
f, msm_size, py_felt=True
f, msm_size, py_felt=True, batched=batched
)
return FunctionFeltCircuit(
name=name,
Expand Down
33 changes: 29 additions & 4 deletions hydra/garaga/precompiled_circuits/all_circuits.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
FixedG2MPCheckBit0,
FixedG2MPCheckBit00,
FixedG2MPCheckBit1,
FixedG2MPCheckBit01,
FixedG2MPCheckBit10,
FixedG2MPCheckFinalizeBN,
FixedG2MPCheckInitBit,
FP12MulAssertOne,
Expand Down Expand Up @@ -91,6 +93,8 @@ class CircuitID(Enum):
MP_CHECK_BIT0_LOOP = int.from_bytes(b"mp_check_bit0_loop", "big")
MP_CHECK_BIT00_LOOP = int.from_bytes(b"mp_check_bit00_loop", "big")
MP_CHECK_BIT1_LOOP = int.from_bytes(b"mp_check_bit1_loop", "big")
MP_CHECK_BIT01_LOOP = int.from_bytes(b"mp_check_bit01_loop", "big")
MP_CHECK_BIT10_LOOP = int.from_bytes(b"mp_check_bit10_loop", "big")
MP_CHECK_PREPARE_PAIRS = int.from_bytes(b"mp_check_prepare_pairs", "big")
MP_CHECK_PREPARE_LAMBDA_ROOT = int.from_bytes(
b"mp_check_prepare_lambda_root", "big"
Expand Down Expand Up @@ -163,12 +167,15 @@ class CircuitID(Enum):
},
CircuitID.EVAL_FUNCTION_CHALLENGE_DUPL: {
"class": EvalFunctionChallengeDuplCircuit,
"params": [{"n_points": k} for k in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]],
"params": [
{"n_points": k, "batched": True} for k in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
]
+ [{"n_points": k, "batched": False} for k in [1, 2]],
"filename": "ec",
},
CircuitID.INIT_FUNCTION_CHALLENGE_DUPL: {
"class": InitFunctionChallengeDuplCircuit,
"params": [{"n_points": k} for k in [11]],
"params": [{"n_points": k, "batched": True} for k in [11]],
"filename": "ec",
},
CircuitID.ACC_FUNCTION_CHALLENGE_DUPL: {
Expand Down Expand Up @@ -208,7 +215,7 @@ class CircuitID(Enum):
{"n_pairs": 3, "n_fixed_g2": 2}, # Groth16
],
"filename": "multi_pairing_check",
"curve_ids": [CurveID.BN254, CurveID.BLS12_381],
"curve_ids": [CurveID.BLS12_381],
},
CircuitID.MP_CHECK_BIT00_LOOP: {
"class": FixedG2MPCheckBit00,
Expand All @@ -226,7 +233,25 @@ class CircuitID(Enum):
{"n_pairs": 3, "n_fixed_g2": 2}, # Groth16
],
"filename": "multi_pairing_check",
"curve_ids": [CurveID.BN254, CurveID.BLS12_381],
"curve_ids": [CurveID.BLS12_381],
},
CircuitID.MP_CHECK_BIT01_LOOP: {
"class": FixedG2MPCheckBit01,
"params": [
{"n_pairs": 2, "n_fixed_g2": 2}, # BLS SIG / KZG Verif
{"n_pairs": 3, "n_fixed_g2": 2}, # Groth16
],
"filename": "multi_pairing_check",
"curve_ids": [CurveID.BN254],
},
CircuitID.MP_CHECK_BIT10_LOOP: {
"class": FixedG2MPCheckBit10,
"params": [
{"n_pairs": 2, "n_fixed_g2": 2}, # BLS SIG / KZG Verif
{"n_pairs": 3, "n_fixed_g2": 2}, # Groth16
],
"filename": "multi_pairing_check",
"curve_ids": [CurveID.BN254],
},
CircuitID.MP_CHECK_PREPARE_PAIRS: {
"class": MPCheckPreparePairs,
Expand Down
Loading

0 comments on commit 4815075

Please sign in to comment.