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
1 change: 1 addition & 0 deletions curdleproofs/curdleproofs/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from .whisk_interface import (
IsValidWhiskShuffleProof,
IsValidWhiskOpeningProof,
GenerateWhiskShuffleProof,
GenerateWhiskTrackerProof,
)
from .opening import TrackerOpeningProof
Expand Down
19 changes: 19 additions & 0 deletions curdleproofs/curdleproofs/test_curdleproofs.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@
from curdleproofs.whisk_interface import (
WhiskTracker,
GenerateWhiskTrackerProof,
GenerateWhiskShuffleProof,
IsValidWhiskOpeningProof,
IsValidWhiskShuffleProof,
)


Expand Down Expand Up @@ -636,6 +638,15 @@ def test_whisk_interface_tracker_opening_proof():
assert IsValidWhiskOpeningProof(tracker, k_commitment, tracker_proof)


def test_whisk_interface_shuffle_proof():
N = 64
ell = N - N_BLINDERS
crs = generate_random_crs(ell)
pre_trackers = generate_random_trackers(ell)
post_trackers, m, shuffle_proof = GenerateWhiskShuffleProof(crs, pre_trackers)
assert IsValidWhiskShuffleProof(crs, pre_trackers, post_trackers, m, shuffle_proof)


def generate_random_k() -> Fr:
return generate_blinders(1)[0]

Expand All @@ -649,3 +660,11 @@ def generate_tracker(k: Fr) -> WhiskTracker:
r_G = multiply(G1, int(r))
k_r_G = multiply(r_G, int(k))
return WhiskTracker(normalize(r_G), normalize(k_r_G))


def generate_random_crs(ell: int) -> CurdleproofsCrs:
return CurdleproofsCrs.new(ell, N_BLINDERS)


def generate_random_trackers(n: int) -> List[WhiskTracker]:
return [generate_tracker(generate_random_k()) for _ in range(n)]
57 changes: 45 additions & 12 deletions curdleproofs/curdleproofs/whisk_interface.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
import random
from typing import Container, Sequence, Tuple
from curdleproofs.crs import CurdleproofsCrs
from curdleproofs.curdleproofs import N_BLINDERS, CurdleProofsProof
from curdleproofs.curdleproofs import (
N_BLINDERS,
CurdleProofsProof,
shuffle_permute_and_commit_input,
)
from curdleproofs.curdleproofs_transcript import CurdleproofsTranscript
from curdleproofs.opening import TrackerOpeningProof
from curdleproofs.util import (
PointAffine as BLSG1Point,
affine_to_projective,
Fr,
)
from py_ecc.optimized_bls12_381.optimized_curve import G1
from py_ecc.optimized_bls12_381.optimized_curve import G1, normalize


class WhiskTracker:
Expand All @@ -24,28 +29,56 @@ def __init__(self, r_G: BLSG1Point, k_r_G: BLSG1Point):


def IsValidWhiskShuffleProof(
crs: CurdleproofsCrs,
pre_shuffle_trackers: Sequence[WhiskTracker],
post_shuffle_trackers: Sequence[WhiskTracker],
M: BLSG1Point,
m: BLSG1Point,
shuffle_proof: SerializedCurdleProofsProof,
) -> Tuple[bool, str]:
"""
Verify `post_shuffle_trackers` is a permutation of `pre_shuffle_trackers`.
"""
crs = CurdleproofsCrs.new(len(pre_shuffle_trackers), N_BLINDERS)
vec_R = [pre_shuffle_tracker.r_G for pre_shuffle_tracker in pre_shuffle_trackers]
vec_S = [pre_shuffle_tracker.k_r_G for pre_shuffle_tracker in pre_shuffle_trackers]
vec_R = [tracker.r_G for tracker in pre_shuffle_trackers]
vec_S = [tracker.k_r_G for tracker in pre_shuffle_trackers]

vec_T = [post_shuffle_tracker.r_G for post_shuffle_tracker in post_shuffle_trackers]
vec_U = [
post_shuffle_tracker.k_r_G for post_shuffle_tracker in post_shuffle_trackers
]
vec_T = [tracker.r_G for tracker in post_shuffle_trackers]
vec_U = [tracker.k_r_G for tracker in post_shuffle_trackers]

shuffle_proof_instance = CurdleProofsProof.from_json(shuffle_proof.decode())
M = affine_to_projective(m)

return shuffle_proof_instance.verify(crs, vec_R, vec_S, vec_T, vec_U, M)


def GenerateWhiskShuffleProof(
crs: CurdleproofsCrs, pre_shuffle_trackers: Sequence[WhiskTracker]
) -> Tuple[Sequence[WhiskTracker], BLSG1Point, SerializedCurdleProofsProof]:
permutation = list(range(len(crs.vec_G)))
random.shuffle(permutation)
k = Fr(random.randint(1, Fr.field_modulus))

vec_R = [tracker.r_G for tracker in pre_shuffle_trackers]
vec_S = [tracker.k_r_G for tracker in pre_shuffle_trackers]

vec_T, vec_U, M, vec_m_blinders = shuffle_permute_and_commit_input(
crs, vec_R, vec_S, permutation, k
)

shuffle_proof: CurdleProofsProof = CurdleProofsProof.new(
crs=crs,
vec_R=vec_R,
vec_S=vec_S,
vec_T=vec_T,
vec_U=vec_U,
M=M,
permutation=permutation,
k=k,
vec_m_blinders=vec_m_blinders,
)

M_projective = affine_to_projective(M)
post_trackers = [WhiskTracker(r_G, k_r_G) for r_G, k_r_G in zip(vec_T, vec_U)]

return shuffle_proof_instance.verify(crs, vec_R, vec_S, vec_T, vec_U, M_projective)
return post_trackers, normalize(M), shuffle_proof.to_json().encode()


SerializedWhiskTrackerProof = bytes
Expand Down