Skip to content
Merged
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
33 changes: 14 additions & 19 deletions curdleproofs/curdleproofs/commitment.py
Original file line number Diff line number Diff line change
@@ -1,55 +1,50 @@
from typing import Type, TypeVar
from curdleproofs.util import (
PointProjective,
Fr,
point_projective_from_json,
point_projective_to_json,
BufReader,
g1_to_bytes,
)
from py_ecc.optimized_bls12_381.optimized_curve import (
multiply,
add,
eq,
)
from py_arkworks_bls12381 import G1Point, Scalar


T_GroupCommitment = TypeVar("T_GroupCommitment", bound="GroupCommitment")


class GroupCommitment:
T_1: PointProjective
T_2: PointProjective
T_1: G1Point
T_2: G1Point

def __init__(self, T_1: PointProjective, T_2: PointProjective) -> None:
def __init__(self, T_1: G1Point, T_2: G1Point) -> None:
self.T_1 = T_1
self.T_2 = T_2

@classmethod
def new(
cls: Type[T_GroupCommitment],
crs_G: PointProjective,
crs_H: PointProjective,
T: PointProjective,
r: Fr,
crs_G: G1Point,
crs_H: G1Point,
T: G1Point,
r: Scalar,
) -> T_GroupCommitment:
return cls(multiply(crs_G, int(r)), add(T, multiply(crs_H, int(r))))
return cls(crs_G * r, T + crs_H * r)

def __add__(self: T_GroupCommitment, other: object) -> T_GroupCommitment:
if not isinstance(other, GroupCommitment):
return NotImplemented
return type(self)(add(self.T_1, other.T_1), add(self.T_2, other.T_2))
return type(self)(self.T_1 + other.T_1, self.T_2 + other.T_2)

def __mul__(self: T_GroupCommitment, other: object) -> T_GroupCommitment:
if not isinstance(other, Fr):
if not isinstance(other, Scalar):
return NotImplemented
return type(self)(
multiply(self.T_1, int(other)), multiply(self.T_2, int(other))
self.T_1 * other, self.T_2 * other
)

def __eq__(self: T_GroupCommitment, __o: object) -> bool:
if not isinstance(__o, GroupCommitment):
return NotImplemented
return eq(self.T_1, __o.T_1) and eq(self.T_2, __o.T_2)
return self.T_1 == __o.T_1 and self.T_2 == __o.T_2

def to_json(self):
return {
Expand Down
30 changes: 14 additions & 16 deletions curdleproofs/curdleproofs/crs.py
Original file line number Diff line number Diff line change
@@ -1,32 +1,30 @@
from functools import reduce
import json
from typing import List, Type, TypeVar
from py_ecc.optimized_bls12_381.optimized_curve import (
add,
Z1
)
from curdleproofs.util import (
PointProjective,
get_random_point,
point_projective_from_json,
point_projective_to_json,
BufReader,
g1_to_bytes,
Z1
)
from py_arkworks_bls12381 import G1Point


T_CurdleproofsCrs = TypeVar("T_CurdleproofsCrs", bound="CurdleproofsCrs")


class CurdleproofsCrs:
def __init__(
self,
vec_G: List[PointProjective],
vec_H: List[PointProjective],
H: PointProjective,
G_t: PointProjective,
G_u: PointProjective,
G_sum: PointProjective,
H_sum: PointProjective,
vec_G: List[G1Point],
vec_H: List[G1Point],
H: G1Point,
G_t: G1Point,
G_u: G1Point,
G_sum: G1Point,
H_sum: G1Point,
) -> None:
self.vec_G = vec_G
self.vec_H = vec_H
Expand All @@ -41,11 +39,11 @@ def new(
cls: Type[T_CurdleproofsCrs], ell: int, n_blinders: int
) -> T_CurdleproofsCrs:
count = ell + n_blinders + 3
points: List[PointProjective] = [get_random_point() for _ in range(0, count)]
points: List[G1Point] = [get_random_point() for _ in range(0, count)]
return cls.from_random_points(ell, n_blinders, points)

@classmethod
def from_random_points(cls: Type[T_CurdleproofsCrs], ell: int, n_blinders: int, points: List[PointProjective]) -> T_CurdleproofsCrs:
def from_random_points(cls: Type[T_CurdleproofsCrs], ell: int, n_blinders: int, points: List[G1Point]) -> T_CurdleproofsCrs:
vec_G = points[0:ell]
vec_H = points[ell:ell + n_blinders]
return cls(
Expand All @@ -54,8 +52,8 @@ def from_random_points(cls: Type[T_CurdleproofsCrs], ell: int, n_blinders: int,
H=points[ell + n_blinders + 0],
G_t=points[ell + n_blinders + 1],
G_u=points[ell + n_blinders + 2],
G_sum=reduce(add, vec_G, Z1),
H_sum=reduce(add, vec_H, Z1),
G_sum=reduce(lambda a, b: a + b, vec_G, Z1),
H_sum=reduce(lambda a, b: a + b, vec_H, Z1),
)

def to_json(self) -> str:
Expand Down
93 changes: 41 additions & 52 deletions curdleproofs/curdleproofs/curdleproofs.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import json
import random
from curdleproofs.crs import CurdleproofsCrs
from curdleproofs.ipa import generate_blinders
from curdleproofs.util import (
Expand All @@ -9,25 +8,18 @@
points_projective_to_bytes,
BufReader,
g1_to_bytes,
random_scalar,
Z1,
)
from curdleproofs.curdleproofs_transcript import CurdleproofsTranscript
from typing import List, Tuple, Type, TypeVar
from curdleproofs.util import (
PointProjective,
Fr,
get_permutation,
)
from curdleproofs.util import get_permutation, g1_is_inf
from curdleproofs.msm_accumulator import MSMAccumulator, compute_MSM
from py_ecc.optimized_bls12_381.optimized_curve import (
multiply,
add,
Z1,
is_inf,
)
from curdleproofs.same_perm import SamePermutationProof
from curdleproofs.same_msm import SameMSMProof
from curdleproofs.same_scalar import SameScalarProof
from curdleproofs.commitment import GroupCommitment
from py_arkworks_bls12381 import G1Point, Scalar

N_BLINDERS = 4

Expand All @@ -37,11 +29,11 @@
class CurdleProofsProof:
def __init__(
self,
A: PointProjective,
A: G1Point,
cm_T: GroupCommitment,
cm_U: GroupCommitment,
R: PointProjective,
S: PointProjective,
R: G1Point,
S: G1Point,
same_perm_proof: SamePermutationProof,
same_scalar_proof: SameScalarProof,
same_msm_proof: SameMSMProof,
Expand All @@ -59,14 +51,14 @@ def __init__(
def new(
cls: Type[T_CurdleProofsProof],
crs: CurdleproofsCrs,
vec_R: List[PointProjective],
vec_S: List[PointProjective],
vec_T: List[PointProjective],
vec_U: List[PointProjective],
M: PointProjective,
vec_R: List[G1Point],
vec_S: List[G1Point],
vec_T: List[G1Point],
vec_U: List[G1Point],
M: G1Point,
permutation: List[int],
k: Fr,
vec_m_blinders: List[Fr],
k: Scalar,
vec_m_blinders: List[Scalar],
) -> T_CurdleProofsProof:
ell = len(vec_R)

Expand All @@ -79,13 +71,10 @@ def new(
vec_a = transcript.get_and_append_challenges(b"curdleproofs_vec_a", ell)

vec_a_blinders = generate_blinders(N_BLINDERS - 2)
vec_r_a_prime = vec_a_blinders + [Fr.zero(), Fr.zero()]
vec_r_a_prime = vec_a_blinders + [Scalar(0), Scalar(0)]
vec_a_permuted = get_permutation(vec_a, permutation)

A = add(
compute_MSM(crs.vec_G, vec_a_permuted),
compute_MSM(crs.vec_H, vec_r_a_prime),
)
A = compute_MSM(crs.vec_G, vec_a_permuted) + compute_MSM(crs.vec_H, vec_r_a_prime)

same_perm_proof = SamePermutationProof.new(
crs_G_vec=crs.vec_G,
Expand All @@ -100,16 +89,16 @@ def new(
transcript=transcript,
)

r_t = Fr(random.randint(1, Fr.field_modulus))
r_u = Fr(random.randint(1, Fr.field_modulus))
r_t = random_scalar()
r_u = random_scalar()
R = compute_MSM(vec_R, vec_a)
S = compute_MSM(vec_S, vec_a)

cm_T: GroupCommitment = GroupCommitment.new(
crs.G_t, crs.H, multiply(R, int(k)), r_t
crs.G_t, crs.H, R * k, r_t
)
cm_U: GroupCommitment = GroupCommitment.new(
crs.G_u, crs.H, multiply(S, int(k)), r_u
crs.G_u, crs.H, S * k, r_u
)

same_scalar_proof = SameScalarProof.new(
Expand All @@ -126,7 +115,7 @@ def new(
transcript=transcript,
)

A_prime = add(add(A, cm_T.T_1), cm_U.T_1)
A_prime = A + cm_T.T_1 + cm_U.T_1

vec_G_with_blinders = (
crs.vec_G + crs.vec_H[: (N_BLINDERS - 2)] + [crs.G_t, crs.G_u]
Expand Down Expand Up @@ -173,18 +162,18 @@ def new(
def verify(
self,
crs: CurdleproofsCrs,
vec_R: List[PointProjective],
vec_S: List[PointProjective],
vec_T: List[PointProjective],
vec_U: List[PointProjective],
M: PointProjective,
vec_R: List[G1Point],
vec_S: List[G1Point],
vec_T: List[G1Point],
vec_U: List[G1Point],
M: G1Point,
):
ell = len(vec_R)

transcript = CurdleproofsTranscript(b"curdleproofs")
msm_accumulator = MSMAccumulator()

if is_inf(vec_T[0]):
if g1_is_inf(vec_T[0]):
raise Exception("vec_T[0] is infinity")

transcript.append_list(
Expand Down Expand Up @@ -218,7 +207,7 @@ def verify(
transcript=transcript,
)

A_prime = add(add(self.A, self.cm_T.T_1), self.cm_U.T_1)
A_prime = self.A + self.cm_T.T_1 + self.cm_U.T_1

vec_G_with_blinders = (
crs.vec_G + crs.vec_H[: (N_BLINDERS - 2)] + [crs.G_t, crs.G_u]
Expand Down Expand Up @@ -311,23 +300,23 @@ def from_bytes(cls: Type[T_CurdleProofsProof], b: BufReader, n: int) -> T_Curdle

def shuffle_permute_and_commit_input(
crs: CurdleproofsCrs,
vec_R: List[PointProjective],
vec_S: List[PointProjective],
vec_R: List[G1Point],
vec_S: List[G1Point],
permutation: List[int],
k: Fr,
) -> Tuple[List[PointProjective], List[PointProjective], PointProjective, List[Fr]]:
k: Scalar,
) -> Tuple[List[G1Point], List[G1Point], G1Point, List[Scalar]]:
ell = len(crs.vec_G)

vec_T = [multiply(R, int(k)) for R in vec_R]
vec_U = [multiply(S, int(k)) for S in vec_S]
vec_T = [R * k for R in vec_R]
vec_U = [S * k for S in vec_S]
vec_T = get_permutation(vec_T, permutation)
vec_U = get_permutation(vec_U, permutation)

range_as_fr = [Fr(i) for i in range(ell)]
range_as_fr = [Scalar(i) for i in range(ell)]
sigma_ell = get_permutation(range_as_fr, permutation)

vec_m_blinders = generate_blinders(N_BLINDERS)
M = add(compute_MSM(crs.vec_G, sigma_ell), compute_MSM(crs.vec_H, vec_m_blinders))
M = compute_MSM(crs.vec_G, sigma_ell) + compute_MSM(crs.vec_H, vec_m_blinders)

return vec_T, vec_U, M, vec_m_blinders

Expand All @@ -338,11 +327,11 @@ def shuffle_permute_and_commit_input(
class VerifierInput:
def __init__(
self,
vec_R: List[PointProjective],
vec_S: List[PointProjective],
vec_T: List[PointProjective],
vec_U: List[PointProjective],
M: PointProjective,
vec_R: List[G1Point],
vec_S: List[G1Point],
vec_T: List[G1Point],
vec_U: List[G1Point],
M: G1Point,
) -> None:
self.vec_R = vec_R
self.vec_S = vec_S
Expand Down
19 changes: 9 additions & 10 deletions curdleproofs/curdleproofs/curdleproofs_transcript.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
from typing import List
from py_ecc.secp256k1.secp256k1 import bytes_to_int
from py_ecc.optimized_bls12_381.optimized_curve import curve_order
from merlin import MerlinTranscript

from curdleproofs.util import Fr
from py_arkworks_bls12381 import Scalar
from curdleproofs.util import CURVE_ORDER


class CurdleproofsTranscript(MerlinTranscript):
Expand All @@ -14,18 +12,19 @@ def append_list(self, label: bytes, items: List[bytes]) -> None:
for item in items:
self.append_message(label, item)

def get_and_append_challenge(self, label: bytes) -> Fr:
def get_and_append_challenge(self, label: bytes) -> Scalar:
while True:
challenge_bytes = self.challenge_bytes(label, 32)
challenge_int = bytes_to_int(challenge_bytes)
if challenge_int >= curve_order:
challenge_int = int.from_bytes(challenge_bytes, byteorder='little')
if challenge_int >= CURVE_ORDER:
continue
f = Fr(challenge_int)
if f != Fr.zero():
# `Scalar.from_le_bytes` will error if value if >= CURVE_ORDER
f = Scalar.from_le_bytes(challenge_bytes)
if not f.is_zero():
self.append(label, challenge_bytes)
return f

def get_and_append_challenges(self, label: bytes, n: int) -> List[Fr]:
def get_and_append_challenges(self, label: bytes, n: int) -> List[Scalar]:
return [self.get_and_append_challenge(label) for _ in range(0, n)]


Expand Down
Loading