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

Voting app and indexer #238

Draft
wants to merge 12 commits into
base: drand-voting
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/wasm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ jobs:
run: |
sudo apt-get update
sudo apt-get install -y \
libnss3 libxss1 libasound2 libatk-bridge2.0-0 libatk1.0-0 \
libnss3 libxss1 libasound2t64 libatk-bridge2.0-0 libatk1.0-0 \
libcups2 libxcomposite1 libxdamage1 libxrandr2 libgbm1 \
libpango-1.0-0 libpangocairo-1.0-0 libpangoft2-1.0-0 libgtk-3-0
- name: Download package file as artifact
Expand Down
6 changes: 6 additions & 0 deletions hydra/garaga/definitions.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,20 @@

class ProofSystem(Enum):
Groth16 = "groth16"
Risc0Groth16 = "risc0_groth16"
UltraKeccakHonk = "ultra_keccak_honk"
UltraStarknetHonk = "ultra_starknet_honk"

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


Expand Down
66 changes: 57 additions & 9 deletions hydra/garaga/precompiled_circuits/honk.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import copy
import math
from abc import ABC, abstractmethod
from dataclasses import dataclass, fields
from enum import Enum, auto

import sha3

import garaga.hints.io as io
import garaga.modulo_circuit_structs as structs
from garaga.definitions import CURVES, CurveID, G1Point, G2Point
from garaga.definitions import CURVES, CurveID, G1Point, G2Point, ProofSystem
from garaga.extension_field_modulo_circuit import ModuloCircuit, ModuloCircuitElement
from garaga.poseidon_transcript import hades_permutation

NUMBER_OF_SUBRELATIONS = 26
NUMBER_OF_ALPHAS = NUMBER_OF_SUBRELATIONS - 1
Expand Down Expand Up @@ -443,23 +445,62 @@ def to_circuit_elements(self, circuit: ModuloCircuit) -> "HonkVk":
)


class Sha3Transcript:
class Transcript(ABC):
def __init__(self):
self.hasher = sha3.keccak_256()
self.reset()

@abstractmethod
def reset(self):
pass

@abstractmethod
def update(self, data: bytes):
pass

@abstractmethod
def digest(self) -> bytes:
pass

def digest_reset(self) -> bytes:
res_bytes = self.digest()
self.reset()
return res_bytes


class Sha3Transcript(Transcript):
def reset(self):
self.hasher = sha3.keccak_256()

def digest(self) -> bytes:
res = self.hasher.digest()
res_int = int.from_bytes(res, "big")
res_mod = res_int % CURVES[CurveID.GRUMPKIN.value].p
res_bytes = res_mod.to_bytes(32, "big")

self.hasher = sha3.keccak_256()
return res_bytes

def update(self, data: bytes):
self.hasher.update(data)


class StarknetPoseidonTranscript(Transcript):
def reset(self):
self.s0, self.s1, self.s2 = hades_permutation(
int.from_bytes(b"StarknetHonk", "big"), 0, 1
)

def digest(self) -> bytes:
res_bytes = self.s0.to_bytes(32, "big")
return res_bytes

def update(self, data: bytes):
val = int.from_bytes(data, "big")
assert val < 2**256
high, low = divmod(val, 2**128)
self.s0, self.s1, self.s2 = hades_permutation(
self.s0 + low, self.s1 + high, self.s2
)


@dataclass
class HonkTranscript:
eta: int | ModuloCircuitElement
Expand All @@ -480,10 +521,11 @@ def __post_init__(self):
assert len(self.alphas) == NUMBER_OF_ALPHAS
assert len(self.gate_challenges) == CONST_PROOF_SIZE_LOG_N
assert len(self.sum_check_u_challenges) == CONST_PROOF_SIZE_LOG_N
self.hasher = sha3.keccak_256()

@classmethod
def from_proof(cls, proof: HonkProof) -> "HonkTranscript":
def from_proof(
cls, proof: HonkProof, system: ProofSystem = ProofSystem.UltraKeccakHonk
) -> "HonkTranscript":
def g1_to_g1_proof_point(g1_proof_point: G1Point) -> tuple[int, int, int, int]:
x_high, x_low = divmod(g1_proof_point.x, G1_PROOF_POINT_SHIFT)
y_high, y_low = divmod(g1_proof_point.y, G1_PROOF_POINT_SHIFT)
Expand All @@ -497,7 +539,13 @@ def split_challenge(ch: bytes) -> tuple[int, int]:
# Round 0 : circuit_size, public_inputs_size, public_input_offset, [public_inputs], w1, w2, w3
FR = CURVES[CurveID.GRUMPKIN.value].p

hasher = Sha3Transcript()
match system:
case ProofSystem.UltraKeccakHonk:
hasher = Sha3Transcript()
case ProofSystem.UltraStarknetHonk:
hasher = StarknetPoseidonTranscript()
case _:
raise ValueError(f"Proof system {system} not compatible")

hasher.update(int.to_bytes(proof.circuit_size, 32, "big"))
hasher.update(int.to_bytes(proof.public_inputs_size, 32, "big"))
Expand Down Expand Up @@ -1901,7 +1949,7 @@ def remove_unused_indexes(array: list) -> list:
print(proof.to_cairo())
print(f"\n\n")

tp = HonkTranscript.from_proof(proof)
tp = HonkTranscript.from_proof(proof, ProofSystem.UltraKeccakHonk)
print(f"\n\n")
print(tp.to_cairo())

Expand Down
Loading
Loading