Skip to main content

zkp-playground is a playground for ZKP algorithms.

Project description

zkp-playground


Description

zkp-playground is a playground for ZKP algorithms.

The project was created on the basis of the Klefki and Plonk_Py libraries.

Klefki Documentation

Requirements:

  • python>=3.6

Installation

pip3 install zkp_playground

zkp_playground shell

ZKP Examples

  • Groth16
from zkp_playground.curves.bns.bn128 import BN128ScalarFP as FP, ECGBN128 as ECG
from zkp_playground.zkp.groth16 import groth16
from zkp_playground.zkp.groth16.r1cs import R1CS
from zkp_playground.zkp.groth16.qap import QAP


@R1CS.r1cs(FP)
def f(x, k, c):
    y = x + c + k
    return y ** 3


g = ECG.G1
h = ECG.G2

qap = QAP(f.A, f.B, f.C)
U, V, W, T = qap.qap
a = f.witness(FP(89), FP(8), FP(8))
H = qap.H(a)
R = groth16.RationalGenerator(
    FP, ECG, ECG, ECG, ECG.e, ECG.G1, ECG.G2, 4, U, V, W, T)

tau, sigma = groth16.setup(R, len(a))
pi = groth16.prov(R, H, tau, sigma, a)
assert groth16.vfy(R, tau, a, pi)
  • Plonk
from zkp_playground.zkp.plonk.trusted_setup import setup_algo
from zkp_playground.zkp.plonk.prover import prover_algo
from zkp_playground.zkp.plonk.verifier import verifier_algo


def permute_idices(wires: list[str]) -> list[int]:
    # This function takes an array "circuit" of arbitrary values and returns an
    # array with shuffles the indices of "circuit" for repeating values
    size = len(wires)
    permutation = [i + 1 for i in range(size)]
    for i in range(size):
        for j in range(i + 1, size):
            if wires[i] == wires[j]:
                permutation[i], permutation[j] = permutation[j], permutation[i]
                break
    return permutation


# Wires
a = ["x", "var1", "var2", "1", "1", "var3", "empty1", "empty2"]
b = ["x", "x", "x", "5", "35", "5", "empty3", "empty4"]
c = ["var1", "var2", "var3", "5", "35", "35", "empty5", "empty6"]

wires = a + b + c

# Gates
add = [1, 1, 0, -1, 0]
mul = [0, 0, 1, -1, 0]
const5 = [0, 1, 0, 0, -5]
public_input = [0, 1, 0, 0, 0]
empty = [0, 0, 0, 0, 0]

gates_matrix = [mul, mul, add, const5, public_input, add, empty, empty]
permutation = permute_idices(wires)

# We can provide public input 35. For that we need to specify the position
# of the gate in L and the value of the public input in p_i
L = [4]
p_i = 35
public_inputs = (L, p_i)

n = len(gates_matrix)
# matrix transpose
gates_matrix = list(zip(*gates_matrix))

# To get the witness, the prover applies his private input x=3 to the
# circuit and writes down the value of every wire.
witness = [
    3, 9, 27, 1, 1, 30, 0, 0,
    3, 3, 3, 5, 35, 5, 0, 0,
    9, 27, 30, 5, 35, 35, 0, 0,
]

# We start with a setup that computes the trusted setup and does some
# precomputation
CRS, Qs, p_i_poly, perm_prep, verifier_prep = setup_algo(
    gates_matrix, permutation, *public_inputs
)

# The prover calculates the proof
proof_SNARK, u = prover_algo(witness, CRS, Qs, p_i_poly, perm_prep)

# Verifier checks if proof checks out
verifier_algo(proof_SNARK, n, p_i_poly, verifier_prep, perm_prep[2])

Elliptic Curve Group Example

  • Test pairing
from zkp_playground.curves.bns import bn128

G1 = bn128.ECGBN128.G1
G2 = bn128.ECGBN128.G2
G = G1
e = bn128.ECGBN128.e

one = bn128.BN128FP12.one()
p1 = e(G1, G2)
p2 = e(G1 @ 2, G2)
assert p1 * p1 == p2
  • Create Custom Groups
import zkp_playground.const as const
from zkp_playground.algebra.fields import FiniteField
from zkp_playground.algebra.groups import EllipticCurveGroup
from zkp_playground.curves.arith import short_weierstrass_form_curve_addition


class FiniteFieldSecp256k1(FiniteField):
    P = const.SECP256K1_P


class FiniteFieldCyclicSecp256k1(FiniteField):
    P = const.SECP256K1_N


class EllipticCurveGroupSecp256k1(EllipticCurveGroup):
    """
    y^2 = x^3 + A * x + B
    """

    N = const.SECP256K1_N
    A = const.SECP256K1_A
    B = const.SECP256K1_B

    def op(self, g):
        field = self.id[0].__class__
        x, y = short_weierstrass_form_curve_addition(
            self.x, self.y,
            g.x, g.y,
            field.zero(),
            field.zero(),
            field.zero(),
            field(self.A),
            field(self.B),
            field
        )
        if x == y == field(0):
            return self.__class__(0)
        return self.__class__((x, y))

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

zkp-playground-1.0.0.tar.gz (68.7 kB view hashes)

Uploaded Source

Built Distribution

zkp_playground-1.0.0-py3-none-any.whl (92.1 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page