Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend Operators #27

Merged
merged 29 commits into from
Aug 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
91a8560
Add .zkif files to gitignore
gxavier38 Jun 17, 2021
38454e1
Move fixedpoint back to its own file
gxavier38 Jun 10, 2021
e9d5620
Add LinComb operators
gxavier38 Jun 21, 2021
d0d85d2
Add fixedpoint operators
gxavier38 Jun 21, 2021
cb8c489
Add LinCombBool and add bitwise ops to LinComb
gxavier38 Jun 21, 2021
73212f4
Add tests
gxavier38 Jun 21, 2021
6d2fb8a
Add CircleCI
gxavier38 Jun 21, 2021
c75f476
Rename ggh_hash
gxavier38 Jun 16, 2021
9b7e12f
Add Poseidon hash
gxavier38 Jun 17, 2021
8d7e4bb
Fix benchmark comment
gxavier38 Jun 21, 2021
2cb743e
Add scaling back to constructor in LinCombFxp
gxavier38 Jun 22, 2021
47edd87
Fix Poseidon dropping LinCombFxps and LinCombBools
gxavier38 Jun 22, 2021
a5d7534
Make fixedpoint truediv lose resolution rather than throw an error
gxavier38 Jun 22, 2021
00a4456
Fix truediv constraint with ignore_errors
gxavier38 Jun 29, 2021
87a9030
Make divmod return PrivVal instead of ConstVal
gxavier38 Jun 29, 2021
7c93f8c
Add missing division constraint and update constraint docs
gxavier38 Jun 29, 2021
ea49bc2
Remove unneeded scaling in fixedpoint multiplication
gxavier38 Jul 6, 2021
ebe33c0
Make LinComb rshift use to_bits
gxavier38 Jul 6, 2021
ab6b8c3
Add more bench tests for LinCombFxp operations
gxavier38 Jul 6, 2021
277e8ca
Improve LinCombBool __pow__
gxavier38 Jul 12, 2021
a63f950
Remove unneeded constraint from assert_range
gxavier38 Jul 12, 2021
63b1d37
Simplify check_nonzero
gxavier38 Jul 12, 2021
b0bbeb0
Improve check_zero performance
gxavier38 Jul 12, 2021
2dfc9a1
Allow unlimited exponents in pow
gxavier38 Jul 12, 2021
13d2bd8
Allow boolean operations with non-bool/non-int types
gxavier38 Jul 12, 2021
2b4ce09
Test LinCombBool operators with non-LinComb types
gxavier38 Jul 12, 2021
347c89b
Fix scaling removal in LinCombFxp.__mul__
gxavier38 Jul 12, 2021
9063e2c
Remove unneeded comment
gxavier38 Jul 12, 2021
b3c8971
Increase nobackend modulus to pass tests
gxavier38 Jul 15, 2021
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
129 changes: 129 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
# Circle CI configuration file
# https://circleci.com/docs/

version: 2.1

commands:
pip-install:
description: Upgrade pip
steps:
- run:
name: Upgrade pip
command: |
python -m pip install --upgrade --user pip
python -m pip install --upgrade --user wheel
python -m pip install --upgrade --user setuptools

install-dependencies:
steps:
- run:
name: Install dependencies
command: |
pip3 install pytest
pip3 install flatbuffers

run-test:
steps:
- run:
name: Run test
command: |
echo 'export PYTHONPATH=$PWD/src' >> $BASH_ENV
pytest

setup-nobackend:
steps:
- run:
name: Set nobackend backend
command: |
echo 'export PYSNARK_BACKEND=nobackend' >> $BASH_ENV

setup-libsnark:
steps:
- run:
name: Set libsnark backend
command: |
pip3 install python-libsnark
echo 'export PYSNARK_BACKEND=libsnark' >> $BASH_ENV

setup-zkinterface:
steps:
- run:
name: Set zkinterface backend
command: |
echo 'export PYSNARK_BACKEND=zkinterface' >> $BASH_ENV

setup-qaptools:
steps:
- run:
name: Set qaptools backend
command: |
echo 'export PYSNARK_BACKEND=qaptools' >> $BASH_ENV

setup-snarkjs:
steps:
- run:
name: Set snarkjs backend
command: |
npm install snarkjs
echo 'export PYSNARK_BACKEND=snarkjs' >> $BASH_ENV

jobs:
test-nobackend:
docker:
- image: cimg/python:3.7
steps:
- checkout
- pip-install
- install-dependencies
- setup-nobackend
- run-test

test-libsnark:
docker:
- image: cimg/python:3.7
steps:
- checkout
- pip-install
- install-dependencies
- setup-libsnark
- run-test

test-zkinterface:
docker:
- image: cimg/python:3.7
steps:
- checkout
- pip-install
- install-dependencies
- setup-zkinterface
- run-test

test-qaptools:
docker:
- image: cimg/python:3.7
steps:
- checkout
- pip-install
- install-dependencies
- setup-qaptools
- run-test

test-snarkjs:
docker:
- image: cimg/python:3.7-node
steps:
- checkout
- pip-install
- install-dependencies
- setup-snarkjs
- run-test

workflows:
version: 2
build:
jobs:
- test-nobackend
- test-libsnark
- test-zkinterface
- test-qaptools
- test-snarkjs
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,5 @@ examples/cubeint.py
pysnark_ek
pysnark_log
pysnark_vk
computation.zkif
circuit.zkif
200 changes: 3 additions & 197 deletions examples/bench.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import pysnark.runtime

from pysnark.runtime import PrivVal, LinComb, benchmark, guarded
from pysnark.boolean import LinCombBool
from pysnark.branching import if_then_else, _while

def count_ops(fn):
Expand Down Expand Up @@ -53,7 +54,7 @@ def benchmark_lin_bl(fn):
pysnark.runtime.bitlength = 7
op6 = count_ops(guarded(LinComb.ONE)(fn))
coef2 = (op5-op4)//2
const2 = op4-3*coef
const2 = op4-3*coef2
if op6!=const2+7*coef2:
raise AssertionError("benchmark_lin_bl: constraints not linear in bitlength")

Expand Down Expand Up @@ -91,199 +92,4 @@ def several(lst):
print("__truediv__ (const) ", benchmark_con_bl(lambda:LinComb.ONE/1))
print("__truediv__ (val) ", benchmark_con_bl(lambda:LinComb.ONE/LinComb.ONE))

# def __floordiv__(self, other):
# """ Division with rounding """
# return self.__divmod__(other)[0]
#
# def __mod__(self, other):
# if other&(other-1)==0:
# # this is faster for powers of two
# return LinComb.from_bits(self.to_bits()[:other.bit_length()-1])
#
# return self.__divmod__(other)[1]
#
# def __divmod__(self, divisor):
# """ Division by public value """
#
# if not is_base_value(divisor): return NotImplemented
#
# if divisor==0: raise ValueError("division by zero")
#
# quo = PrivVal(self.value//divisor)
# rem = PrivVal(self.value-quo.value*divisor)
#
# rem.assert_positive(divisor.bit_length())
# if divisor&(divisor-1)!=0: rem.assert_lt(divisor) # not needed for powers of two
# quo.assert_positive()
# (self-divisor*quo-rem).assert_zero()
#
# return (quo,rem)
#
# def __pow__(self, other, mod=None):
# """ Exponentiation with public integral power p>=0 """
# if mod!=None: raise ValueError("cannot provide modulus")
# if not is_base_value(other): return NotImplemented
# if other<0: raise ValueError("exponent cannot be negative", other)
# if other==0: return LinComb.ONE
# if other==1: return self
# return self*pow(self, other-1)
#
# def __lshift__(self, other):
# """ Left-shift with public value """
# # TODO: extend to secret offset?
# if not is_base_ovalue(other): return NotImplemented
# return self*(1<<other)
#
# def __rshift__(self, other):
# """ Right-shift with public value """
# # TODO: extend to secret offset?
# if not is_base_ovalue(other): return NotImplemented
# return LinComb.from_bits(self.to_bits[other:])
#
# def _check_both_bits(self, other):
# if ignore_errors: return
#
# if self.value !=0 and self.value!=1: raise ValueError("not a bit: " + str(self.value))
#
# if isinstance(other, LinComb) and (other.value==0 or other.value==1): return
# if is_base_value(other) and (other==0 or other==1): return
# raise ValueError("not a bit: " + str(other))
#
# def __and__(self, other):
# """ Bitwise and &. Cost: 1 constraint """
# self._check_both_bits(other)
# return self * other
#
# def __xor__(self, other):
# """Bitwise exclusive-or ^. Cost: 1 constraint """
# self._check_both_bits(other)
# return self + other - 2 * self * other
#
# def __or__(self, other):
# """Bitwise or |. Cost: 1 constraint """
# self._check_both_bits(other)
# return self + other - self * other
#
# __radd__ = __add__
#
# def __rsub__(self, other):
# return other+(-self)
#
# __rmul__ = __mul__
#
# def __rmatmul__(self, other): return NotImplemented
#
# def __rtruediv__(self, other):
# """ Proper division by LinComb """
# if not is_base_value(other): return NotImplemented
#
# if other % self.value != 0:
# raise ValueError(str(other.value) + " is not properly divisible by " + str(self.value))
#
# res = PrivVal(other/self.value)
# do_add_constraint(self, res, other*LinComb.ONE)
# return res
#
# def __rfloordiv__(self, other): return NotImplemented
# def __rmod__(self, other): return NotImplemented
# def __rdivmod__(self, other): return NotImplemented
# def __rpow__(self, other): return NotImplemented
# def __rlshift__(self, other): return NotImplemented
# def __rrshift__(self, other): return NotImplemented
#
# __rand__ = __and__
# __rxor__ = __xor__
# __ror__ = __or__
#
# def __neg__(self):
# return LinComb(-self.value, -self.lc)
#
# def __pos__(self):
# return self
#
# def __abs__(self):
# from .branching import if_then_else
# return if_then_else(self>=0, self, -self)
#
# def __invert__(self):
# # we do not want to do ~1=0 and ~0=1 since this is also not true for native ints
# raise NotImplementedError("Operator ~ not supported. For binary not, use 1-x")
#
# def __complex__(self): return NotImplemented
# def __int__(self): raise NotImplementedError("Should not run int() on LinComb")
# def __float__(self): return NotImplemented
#
# def __round__(self, ndigits=None): return NotImplemented
# def __trunc__(self): return NotImplemented
# def __floor__(self): return NotImplemented
# def __ceil__(self): return NotImplemented
#
# def assert_bool(self):
# add_constraint(self, 1-self, LinComb.ZERO)
#
# def assert_bool_unsafe(self):
# add_constraint_unsafe(self, 1-self, LinComb.ZERO)
#
# def to_bits(self, bits=bitlength):
# if (not ignore_errors) and (self.value<0 or self.value.bit_length()>bits):
# raise ValueError("value " + str(self.value) + " is not a " + str(bits) + "-bit positive integer")
#
# bits = [PrivVal((self.value&(1<<ix))>>ix) for ix in range(bits)]
# for bit in bits: bit.assert_bool_unsafe()
#
# (self-LinComb.from_bits(bits)).assert_zero()
#
# return bits
#
# @classmethod
# def from_bits(cls, bits):
# return sum([biti*(1<<i) for (i,biti) in enumerate(bits)])
#
# """
# Given a value in [-1<<bitlength,1>>bitlength], check if it is positive.
# Note that this works on (bitlength+1)-length values so it works for
# __lt__, etc on bitlength-length values
# """
# def check_positive(self, bits=bitlength):
# if (not ignore_errors) and self.value.bit_length()>bits:
# raise ValueError("value " + str(self.value) + " is not a " + str(bits) + "-bit integer")
#
# ret = PrivVal(1 if self.value>=0 else 0)
# abs = self.value if self.value>=0 else -self.value
#
# bits = [PrivVal((abs&(1<<ix))>>ix) for ix in range(bits)]
# for bit in bits: bit.assert_bool_unsafe()
#
# # if ret==1, then requires that 2*self=self+sum, so sum=self
# # if ret==0, this requires that 0=self+sum, so sum=-self
# add_constraint(2*ret, self, self+LinComb.from_bits(bits))
#
# return ret
#
# def assert_positive(self, bits=bitlength):
# self.to_bits(bits)
#
# def check_zero(self):
# ret = PrivVal(1 if self.value==0 else 0)
#
# wit = PrivVal(backend.fieldinverse(self.value+ret.value)) # add ret.value so always nonzero
#
# # Trick from Pinocchio paper: if self is zero then ret=1 by first eq,
# # if self is nonzero then ret=0 by second eq
# add_constraint_unsafe(self, wit, 1-ret)
# add_constraint_unsafe(self, ret, LinComb.ZERO)
#
# return ret
#
# def assert_zero(self):
# if (not ignore_errors) and self.value!=0:
# raise ValueError("Value " + str(self.value) + " is not zero")
#
# add_constraint(LinComb.ZERO, LinComb.ZERO, self)
#
# def assert_nonzero(self):
# if (not ignore_errors) and self.value==0:
# raise ValueError("Value " + str(self.value) + " is not zero")
#
# wit = PrivVal(backend.fieldinverse(self.value if self.value!=0 else 1))
# add_constraint(self, wit, LinComb.ONE)
print("LimCombBool (val) ", benchmark_con_bl(lambda:LinCombBool(LinComb.ONE)))
3 changes: 2 additions & 1 deletion examples/kaplanmeier.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@

import pysnark.runtime

from pysnark.runtime import PrivVal, LinCombFxp
from pysnark.runtime import PrivVal
from pysnark.fixedpoint import LinCombFxp

if __name__ == '__main__':
# example batch of survival data from two populations
Expand Down
Loading