Skip to content

Commit

Permalink
add/double G2 circuits.
Browse files Browse the repository at this point in the history
  • Loading branch information
feltroidprime committed Oct 22, 2024
1 parent 0f39c84 commit 9a4b953
Show file tree
Hide file tree
Showing 3 changed files with 162 additions and 1 deletion.
14 changes: 14 additions & 0 deletions hydra/garaga/precompiled_circuits/all_circuits.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@
AccumulateEvalPointChallengeSignedCircuit,
AccumulateFunctionChallengeDuplCircuit,
AddECPointCircuit,
AddECPointsG2Circuit,
DoubleECPointCircuit,
DoubleECPointG2AEq0Circuit,
DummyCircuit,
EvalFunctionChallengeDuplCircuit,
FinalizeFunctionChallengeDuplCircuit,
Expand Down Expand Up @@ -121,6 +123,8 @@ class CircuitID(Enum):
E12T_DECOMPRESS_KARABINA_PT_II = int.from_bytes(
b"e12t_decompress_karabina_pt_ii", "big"
)
ADD_EC_POINT_G2 = int.from_bytes(b"add_ec_point_g2", "big")
DOUBLE_EC_POINT_G2 = int.from_bytes(b"double_ec_point_g2", "big")


ALL_CAIRO_CIRCUITS = {
Expand Down Expand Up @@ -185,6 +189,16 @@ class CircuitID(Enum):
"params": None,
"filename": "ec",
},
CircuitID.ADD_EC_POINT_G2: {
"class": AddECPointsG2Circuit,
"params": None,
"filename": "ec",
},
CircuitID.DOUBLE_EC_POINT_G2: {
"class": DoubleECPointG2AEq0Circuit,
"params": None,
"filename": "ec",
},
CircuitID.MP_CHECK_BIT0_LOOP: {
"class": FixedG2MPCheckBit0,
"params": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,12 @@
ModuloCircuit,
PyFelt,
)
from garaga.precompiled_circuits.ec import BasicEC, ECIPCircuits, IsOnCurveCircuit
from garaga.precompiled_circuits.ec import (
BasicEC,
BasicECG2,
ECIPCircuits,
IsOnCurveCircuit,
)


class DummyCircuit(BaseModuloCircuit):
Expand Down Expand Up @@ -168,6 +173,81 @@ def _run_circuit_inner(self, input: list[PyFelt]) -> ModuloCircuit:
return circuit


class AddECPointsG2Circuit(BaseModuloCircuit):
def __init__(self, curve_id: int, auto_run: bool = True, compilation_mode: int = 0):
super().__init__(
name="add_ec_points_g2",
curve_id=curve_id,
auto_run=auto_run,
compilation_mode=compilation_mode,
)

def build_input(self) -> list[PyFelt]:
input = []
P = G2Point.gen_random_point(CurveID(self.curve_id))
Q = G2Point.gen_random_point(CurveID(self.curve_id))
input.append(self.field(P.x[0]))
input.append(self.field(P.x[1]))
input.append(self.field(P.y[0]))
input.append(self.field(P.y[1]))
input.append(self.field(Q.x[0]))
input.append(self.field(Q.x[1]))
input.append(self.field(Q.y[0]))
input.append(self.field(Q.y[1]))
return input

def _run_circuit_inner(self, input: list[PyFelt]) -> ModuloCircuit:
circuit = BasicECG2(
self.name, self.curve_id, compilation_mode=self.compilation_mode
)
px0, px1, py0, py1 = circuit.write_struct(
G2PointCircuit("p", input[0:4]), WriteOps.INPUT
)
qx0, qx1, qy0, qy1 = circuit.write_struct(
G2PointCircuit("q", input[4:8]), WriteOps.INPUT
)

(nx0, nx1), (ny0, ny1) = circuit.add_points(
((px0, px1), (py0, py1)), ((qx0, qx1), (qy0, qy1))
)
circuit.extend_struct_output(G2PointCircuit("result", [nx0, nx1, ny0, ny1]))

return circuit


class DoubleECPointG2AEq0Circuit(BaseModuloCircuit):
def __init__(self, curve_id: int, auto_run: bool = True, compilation_mode: int = 0):
super().__init__(
name="double_ec_point_g2_a_eq_0",
curve_id=curve_id,
auto_run=auto_run,
compilation_mode=compilation_mode,
)

def build_input(self) -> list[PyFelt]:
input = []
P = G2Point.gen_random_point(CurveID(self.curve_id))
input.append(self.field(P.x[0]))
input.append(self.field(P.x[1]))
input.append(self.field(P.y[0]))
input.append(self.field(P.y[1]))

return input

def _run_circuit_inner(self, input: list[PyFelt]) -> ModuloCircuit:
circuit = BasicECG2(
self.name, self.curve_id, compilation_mode=self.compilation_mode
)
px0, px1, py0, py1 = circuit.write_struct(
G2PointCircuit("p", input[0:4]), WriteOps.INPUT
)

(nx0, nx1), (ny0, ny1) = circuit.double_point_a_eq_0(((px0, px1), (py0, py1)))
circuit.extend_struct_output(G2PointCircuit("result", [nx0, nx1, ny0, ny1]))

return circuit


class SlopeInterceptSamePointCircuit(BaseModuloCircuit):
def __init__(
self, curve_id: int, auto_run: bool = True, compilation_mode: int = 0
Expand Down
67 changes: 67 additions & 0 deletions hydra/garaga/precompiled_circuits/ec.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from garaga.definitions import CURVES
from garaga.extension_field_modulo_circuit import (
ExtensionFieldModuloCircuit,
ModuloCircuit,
ModuloCircuitElement,
PyFelt,
Expand Down Expand Up @@ -593,3 +594,69 @@ def _is_on_curve_G2_weirstrass(
x3_ax_b = [self.add(x3[0], ax_b[0]), self.add(x3[1], ax_b[1])]

return y2, x3_ax_b


class BasicECG2(ExtensionFieldModuloCircuit):
def __init__(self, name: str, curve_id: int, compilation_mode: int = 0):
super().__init__(
name=name,
curve_id=curve_id,
extension_degree=2,
generic_circuit=True,
compilation_mode=compilation_mode,
)
self.curve = CURVES[curve_id]

def _compute_adding_slope(
self,
P: tuple[
tuple[ModuloCircuitElement, ModuloCircuitElement],
tuple[ModuloCircuitElement, ModuloCircuitElement],
],
Q: tuple[
tuple[ModuloCircuitElement, ModuloCircuitElement],
tuple[ModuloCircuitElement, ModuloCircuitElement],
],
):
xP, yP = P
xQ, yQ = Q
slope = self.fp2_div(self.extf_sub(yP, yQ), self.extf_sub(xP, xQ))
return slope

def _compute_doubling_slope_a_eq_0(
self,
P: tuple[ModuloCircuitElement, ModuloCircuitElement],
):

xP, yP = P
# Compute doubling slope m = (3x^2 + A) / 2y
three = self.set_or_get_constant(self.field(3))

m_num = self.extf_scalar_mul(self.fp2_square(xP), three)
m_den = self.extf_add(yP, yP)
m = self.fp2_div(m_num, m_den)
return m

def add_points(
self,
P: tuple[ModuloCircuitElement, ModuloCircuitElement],
Q: tuple[ModuloCircuitElement, ModuloCircuitElement],
) -> tuple[ModuloCircuitElement, ModuloCircuitElement]:
xP, yP = P
xQ, yQ = Q
slope = self._compute_adding_slope(P, Q)
slope_sqr = self.fp2_square(slope)
nx = self.extf_sub(self.extf_sub(slope_sqr, xP), xQ)
ny = self.extf_sub(self.fp2_mul(slope, self.extf_sub(xP, nx)), yP)
return (nx, ny)

def double_point_a_eq_0(
self,
P: tuple[ModuloCircuitElement, ModuloCircuitElement],
) -> tuple[ModuloCircuitElement, ModuloCircuitElement]:
xP, yP = P
slope = self._compute_doubling_slope_a_eq_0(P)
slope_sqr = self.fp2_square(slope)
nx = self.extf_sub(self.extf_sub(slope_sqr, xP), xP)
ny = self.extf_sub(yP, self.fp2_mul(slope, self.extf_sub(xP, nx)))
return (nx, ny)

0 comments on commit 9a4b953

Please sign in to comment.