Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
dankrad committed Aug 4, 2021
1 parent 247013f commit 468561e
Show file tree
Hide file tree
Showing 7 changed files with 1,409 additions and 0 deletions.
Binary file added verkle_trie_pedersen/_blst.so
Binary file not shown.
237 changes: 237 additions & 0 deletions verkle_trie_pedersen/blst.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
# This file was automatically generated by SWIG (http://www.swig.org).
# Version 4.0.1
#
# Do not make changes to this file unless you know what you are doing--modify
# the SWIG interface file instead.

from sys import version_info as _swig_python_version_info
if _swig_python_version_info < (2, 7, 0):
raise RuntimeError("Python 2.7 or later required")

# Import the low-level C/C++ module
if __package__ or "." in __name__:
from . import _blst
else:
import _blst

try:
import builtins as __builtin__
except ImportError:
import __builtin__

_swig_new_instance_method = _blst.SWIG_PyInstanceMethod_New
_swig_new_static_method = _blst.SWIG_PyStaticMethod_New

def _swig_repr(self):
try:
strthis = "proxy of " + self.this.__repr__()
except __builtin__.Exception:
strthis = ""
return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,)


def _swig_setattr_nondynamic_instance_variable(set):
def set_instance_attr(self, name, value):
if name == "thisown":
self.this.own(value)
elif name == "this":
set(self, name, value)
elif hasattr(self, name) and isinstance(getattr(type(self), name), property):
set(self, name, value)
else:
raise AttributeError("You cannot add instance attributes to %s" % self)
return set_instance_attr


def _swig_setattr_nondynamic_class_variable(set):
def set_class_attr(cls, name, value):
if hasattr(cls, name) and not isinstance(getattr(cls, name), property):
set(cls, name, value)
else:
raise AttributeError("You cannot add class attributes to %s" % cls)
return set_class_attr


def _swig_add_metaclass(metaclass):
"""Class decorator for adding a metaclass to a SWIG wrapped class - a slimmed down version of six.add_metaclass"""
def wrapper(cls):
return metaclass(cls.__name__, cls.__bases__, cls.__dict__.copy())
return wrapper


class _SwigNonDynamicMeta(type):
"""Meta class to enforce nondynamic attributes (no new attributes) for a class"""
__setattr__ = _swig_setattr_nondynamic_class_variable(type.__setattr__)


BLST_SUCCESS = _blst.BLST_SUCCESS
BLST_BAD_ENCODING = _blst.BLST_BAD_ENCODING
BLST_POINT_NOT_ON_CURVE = _blst.BLST_POINT_NOT_ON_CURVE
BLST_POINT_NOT_IN_GROUP = _blst.BLST_POINT_NOT_IN_GROUP
BLST_AGGR_TYPE_MISMATCH = _blst.BLST_AGGR_TYPE_MISMATCH
BLST_VERIFY_FAIL = _blst.BLST_VERIFY_FAIL
BLST_PK_IS_INFINITY = _blst.BLST_PK_IS_INFINITY
class SecretKey(object):
thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
__repr__ = _swig_repr
keygen = _swig_new_instance_method(_blst.SecretKey_keygen)
from_bendian = _swig_new_instance_method(_blst.SecretKey_from_bendian)
from_lendian = _swig_new_instance_method(_blst.SecretKey_from_lendian)
to_bendian = _swig_new_instance_method(_blst.SecretKey_to_bendian)
to_lendian = _swig_new_instance_method(_blst.SecretKey_to_lendian)

def __init__(self):
_blst.SecretKey_swiginit(self, _blst.new_SecretKey())
__swig_destroy__ = _blst.delete_SecretKey

# Register SecretKey in _blst:
_blst.SecretKey_swigregister(SecretKey)

class P1_Affine(object):
thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
__repr__ = _swig_repr

def __init__(self, *args):
_blst.P1_Affine_swiginit(self, _blst.new_P1_Affine(*args))
dup = _swig_new_instance_method(_blst.P1_Affine_dup)
to_jacobian = _swig_new_instance_method(_blst.P1_Affine_to_jacobian)
serialize = _swig_new_instance_method(_blst.P1_Affine_serialize)
compress = _swig_new_instance_method(_blst.P1_Affine_compress)
on_curve = _swig_new_instance_method(_blst.P1_Affine_on_curve)
in_group = _swig_new_instance_method(_blst.P1_Affine_in_group)
is_inf = _swig_new_instance_method(_blst.P1_Affine_is_inf)
is_equal = _swig_new_instance_method(_blst.P1_Affine_is_equal)
core_verify = _swig_new_instance_method(_blst.P1_Affine_core_verify)
generator = _swig_new_static_method(_blst.P1_Affine_generator)
__swig_destroy__ = _blst.delete_P1_Affine

# Register P1_Affine in _blst:
_blst.P1_Affine_swigregister(P1_Affine)
P1_Affine_generator = _blst.P1_Affine_generator

class P1(object):
thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
__repr__ = _swig_repr

def __init__(self, *args):
_blst.P1_swiginit(self, _blst.new_P1(*args))
dup = _swig_new_instance_method(_blst.P1_dup)
to_affine = _swig_new_instance_method(_blst.P1_to_affine)
serialize = _swig_new_instance_method(_blst.P1_serialize)
compress = _swig_new_instance_method(_blst.P1_compress)
on_curve = _swig_new_instance_method(_blst.P1_on_curve)
in_group = _swig_new_instance_method(_blst.P1_in_group)
is_inf = _swig_new_instance_method(_blst.P1_is_inf)
is_equal = _swig_new_instance_method(_blst.P1_is_equal)
aggregate = _swig_new_instance_method(_blst.P1_aggregate)
sign_with = _swig_new_instance_method(_blst.P1_sign_with)
hash_to = _swig_new_instance_method(_blst.P1_hash_to)
encode_to = _swig_new_instance_method(_blst.P1_encode_to)
mult = _swig_new_instance_method(_blst.P1_mult)
cneg = _swig_new_instance_method(_blst.P1_cneg)
neg = _swig_new_instance_method(_blst.P1_neg)
add = _swig_new_instance_method(_blst.P1_add)
dbl = _swig_new_instance_method(_blst.P1_dbl)
generator = _swig_new_static_method(_blst.P1_generator)
__swig_destroy__ = _blst.delete_P1

# Register P1 in _blst:
_blst.P1_swigregister(P1)
P1_generator = _blst.P1_generator

class P2_Affine(object):
thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
__repr__ = _swig_repr

def __init__(self, *args):
_blst.P2_Affine_swiginit(self, _blst.new_P2_Affine(*args))
dup = _swig_new_instance_method(_blst.P2_Affine_dup)
to_jacobian = _swig_new_instance_method(_blst.P2_Affine_to_jacobian)
serialize = _swig_new_instance_method(_blst.P2_Affine_serialize)
compress = _swig_new_instance_method(_blst.P2_Affine_compress)
on_curve = _swig_new_instance_method(_blst.P2_Affine_on_curve)
in_group = _swig_new_instance_method(_blst.P2_Affine_in_group)
is_inf = _swig_new_instance_method(_blst.P2_Affine_is_inf)
is_equal = _swig_new_instance_method(_blst.P2_Affine_is_equal)
core_verify = _swig_new_instance_method(_blst.P2_Affine_core_verify)
generator = _swig_new_static_method(_blst.P2_Affine_generator)
__swig_destroy__ = _blst.delete_P2_Affine

# Register P2_Affine in _blst:
_blst.P2_Affine_swigregister(P2_Affine)
P2_Affine_generator = _blst.P2_Affine_generator

class P2(object):
thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
__repr__ = _swig_repr

def __init__(self, *args):
_blst.P2_swiginit(self, _blst.new_P2(*args))
dup = _swig_new_instance_method(_blst.P2_dup)
to_affine = _swig_new_instance_method(_blst.P2_to_affine)
serialize = _swig_new_instance_method(_blst.P2_serialize)
compress = _swig_new_instance_method(_blst.P2_compress)
on_curve = _swig_new_instance_method(_blst.P2_on_curve)
in_group = _swig_new_instance_method(_blst.P2_in_group)
is_inf = _swig_new_instance_method(_blst.P2_is_inf)
is_equal = _swig_new_instance_method(_blst.P2_is_equal)
aggregate = _swig_new_instance_method(_blst.P2_aggregate)
sign_with = _swig_new_instance_method(_blst.P2_sign_with)
hash_to = _swig_new_instance_method(_blst.P2_hash_to)
encode_to = _swig_new_instance_method(_blst.P2_encode_to)
mult = _swig_new_instance_method(_blst.P2_mult)
cneg = _swig_new_instance_method(_blst.P2_cneg)
neg = _swig_new_instance_method(_blst.P2_neg)
add = _swig_new_instance_method(_blst.P2_add)
dbl = _swig_new_instance_method(_blst.P2_dbl)
generator = _swig_new_static_method(_blst.P2_generator)
__swig_destroy__ = _blst.delete_P2

# Register P2 in _blst:
_blst.P2_swigregister(P2)
P2_generator = _blst.P2_generator

G1 = _blst.G1
G2 = _blst.G2
class PT(object):
thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
__repr__ = _swig_repr

def __init__(self, *args):
_blst.PT_swiginit(self, _blst.new_PT(*args))
dup = _swig_new_instance_method(_blst.PT_dup)
is_one = _swig_new_instance_method(_blst.PT_is_one)
is_equal = _swig_new_instance_method(_blst.PT_is_equal)
sqr = _swig_new_instance_method(_blst.PT_sqr)
mul = _swig_new_instance_method(_blst.PT_mul)
final_exp = _swig_new_instance_method(_blst.PT_final_exp)
__swig_destroy__ = _blst.delete_PT

# Register PT in _blst:
_blst.PT_swigregister(PT)

class Pairing(object):
thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
__repr__ = _swig_repr

def __init__(self, *args):
_blst.Pairing_swiginit(self, _blst.new_Pairing(*args))
__swig_destroy__ = _blst.delete_Pairing
aggregate = _swig_new_instance_method(_blst.Pairing_aggregate)
mul_n_aggregate = _swig_new_instance_method(_blst.Pairing_mul_n_aggregate)
commit = _swig_new_instance_method(_blst.Pairing_commit)
merge = _swig_new_instance_method(_blst.Pairing_merge)
finalverify = _swig_new_instance_method(_blst.Pairing_finalverify)

# Register Pairing in _blst:
_blst.Pairing_swigregister(Pairing)

cdata = _blst.cdata
memmove = _blst.memmove

cvar = _blst.cvar
BLS12_381_G1 = cvar.BLS12_381_G1
BLS12_381_NEG_G1 = cvar.BLS12_381_NEG_G1
BLS12_381_G2 = cvar.BLS12_381_G2
BLS12_381_NEG_G2 = cvar.BLS12_381_NEG_G2

15 changes: 15 additions & 0 deletions verkle_trie_pedersen/compute_stats.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
echo -e "WIDTH_BITS\tWIDTH\tNUMBER_INITIAL_KEYS\tNUMBER_KEYS_PROOF\taverage_depth\tproof_size\tproof_time\tcheck_time" > stats.txt


python verkle_trie.py 5 65536 500 >> stats.txt
python verkle_trie.py 6 65536 500 >> stats.txt
python verkle_trie.py 7 65536 500 >> stats.txt
python verkle_trie.py 8 65536 500 >> stats.txt
python verkle_trie.py 9 65536 500 >> stats.txt
python verkle_trie.py 10 65536 500 >> stats.txt
python verkle_trie.py 11 65536 500 >> stats.txt
python verkle_trie.py 12 65536 500 >> stats.txt
python verkle_trie.py 13 65536 500 >> stats.txt
python verkle_trie.py 14 65536 500 >> stats.txt
python verkle_trie.py 15 65536 500 >> stats.txt
python verkle_trie.py 16 65536 500 >> stats.txt
114 changes: 114 additions & 0 deletions verkle_trie_pedersen/ipa.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import blst
import pippenger

#
# Utilities for dealing with polynomials in evaluation form
#
# A polynomial in evaluation for is defined by its values on DOMAIN,
# where DOMAIN is [omega**0, omega**1, omega**2, ..., omega**(WIDTH-1)]
# where omega is a WIDTH root of unity, i.e. omega**WIDTH % MODULUS == 1
#
# Any polynomial of degree < WIDTH can be represented uniquely in this form,
# and many operations (such as multiplication and exact division) are more
# efficient.
#
# By precomputing the trusted setup in Lagrange basis, we can also easily
# commit to a a polynomial in evaluation form.
#

class KzgUtils():

"""
Class that defines helper function for Kate proofs in evaluation form (Lagrange basis)
"""
def __init__(self, MODULUS, WIDTH, DOMAIN, SETUP, primefield):
self.MODULUS = MODULUS
self.WIDTH = WIDTH
self.DOMAIN = DOMAIN
self.SETUP = SETUP
self.primefield = primefield
# Precomputed inverses of 1 / (1 - DOMAIN[i])
self.inverses = [0] + [primefield.inv(1 - DOMAIN[i]) for i in range(1, WIDTH)]
self.inverse_width = primefield.inv(self.WIDTH)


def evaluate_polynomial_in_evaluation_form(self, f, z):
"""
Takes a polynomial in evaluation form and evaluates it at one point outside the domain.
Uses the barycentric formula:
f(z) = (1 - z**WIDTH) / WIDTH * sum_(i=0)^WIDTH (f(DOMAIN[i]) * DOMAIN[i]) / (z - DOMAIN[i])
"""
r = 0
for i in range(self.WIDTH):
r += self.primefield.div(f[i] * self.DOMAIN[i], (z - self.DOMAIN[i]) )
r = r * (pow(z, self.WIDTH, self.MODULUS) - 1) * self.inverse_width % self.MODULUS

return r


def compute_inner_quotient_in_evaluation_form(self, f, index):
"""
Compute the quotient q(X) = (f(X) - f(DOMAIN[index])) / (X - DOMAIN[index]) in evaluation form.
Inner means that the value z = DOMAIN[index] is one of the points at which f is evaluated -- so unlike an outer
quotient (where z is not in DOMAIN), we need to do some extra work to compute q[index] where the formula above
is 0 / 0
"""
q = [0] * self.WIDTH
y = f[index]
for i in range(self.WIDTH):
if i != index:
q[i] = (f[i] - y) * self.DOMAIN[-i] * self.inverses[index - i] % self.MODULUS
q[index] += - self.DOMAIN[(i - index) % self.WIDTH] * q[i] % self.MODULUS

return q


def compute_outer_quotient_in_evaluation_form(self, f, z, y):
"""
Compute the quotient q(X) = (f(X) - y)) / (X - z) in evaluation form. Note that this only works if the quotient
is exact, i.e. f(z) = y, and otherwise returns garbage
"""
q = [0] * self.WIDTH
for i in range(self.WIDTH):
q[i] = self.primefield.div(f[i] - y, self.DOMAIN[i] - z)

return q


def check_kzg_proof(self, C, z, y, pi):
"""
Check the KZG proof
e(C - [y], [1]) = e(pi, [s - z])
which is equivalent to
e(C - [y], [1]) * e(-pi, [s - z]) == 1
"""
pairing = blst.PT(blst.G2().to_affine(), C.dup().add(blst.G1().mult(y).neg()).to_affine())
pairing.mul(blst.PT(self.SETUP["g2"][1].dup().add(blst.G2().mult(z).neg()).to_affine(), pi.dup().neg().to_affine()))

return pairing.final_exp().is_one()


def evaluate_and_compute_kzg_proof(self, f, z):
"""
Evaluates a function f (given in evaluation form) at a point z (which can be in the DOMAIN or not)
and gives y = f(z) as well as a Kate proof that this is the correct result
"""
if z in self.DOMAIN:
index = self.DOMAIN.index(z)
y = f[index]
q = self.compute_inner_quotient_in_evaluation_form(f, index)
else:
y = self.evaluate_polynomial_in_evaluation_form(f, z)
q = self.compute_outer_quotient_in_evaluation_form(f, z, y)

return y, pippenger.pippenger_simple(self.SETUP["g1_lagrange"], q)


def compute_commitment_lagrange(self, values):
"""
Computes a commitment for a function given in evaluation form.
'values' is a dictionary and can have missing indices, which improves efficiency.
"""
commitment = pippenger.pippenger_simple([self.SETUP["g1_lagrange"][i] for i in values.keys()], values.values())
return commitment
Loading

0 comments on commit 468561e

Please sign in to comment.