Made pairing impl python3-friendly

This commit is contained in:
vub 2017-02-07 08:39:28 -05:00
parent 2d1dd0227b
commit 00b990d219
5 changed files with 48 additions and 24 deletions

View File

@ -2,14 +2,16 @@
# in the randao-based single-chain Casper.
import random
# Reward for mining a block with nonzero skips
NON_PRIMARY_REWARD = 0.5
# Penalty for mining a dunkle
DUNKLE_PENALTY = 1
DUNKLE_PENALTY = 0.75
# Penalty to a main-chain block which has a dunkle as a sister
DUNKLE_SISTER_PENALTY = 0.8
DUNKLE_SISTER_PENALTY = 0.375
# Attacker stake power (out of 100). Try setting this value to any
# amount, even values above 50!
attacker_share = 40
attacker_share = 60
# A simulated Casper randao
def randao_successor(parent, index):
@ -78,7 +80,7 @@ class Chain():
self.randao = new_randao
self.time += skips
self.length += 1
self.me += 1
self.me += NON_PRIMARY_REWARD if skips else 1
def extend_them(self, skips):
new_randao = randao_successor(self.randao, skips)
@ -86,7 +88,7 @@ class Chain():
self.randao = new_randao
self.time += skips
self.length += 1
self.them += 1
self.them += NON_PRIMARY_REWARD if skips else 1
def add_my_dunkles(self, n):
self.me -= n * DUNKLE_PENALTY
@ -96,7 +98,8 @@ class Chain():
self.them -= n * DUNKLE_PENALTY
self.me -= n * DUNKLE_SISTER_PENALTY
my_total_loss = 0
their_total_loss = 0
for strat_id in range(2**len(scenarios)):
# Strategy map: scenario to 0 = publish, 1 = selfish-validate
@ -105,7 +108,7 @@ for strat_id in range(2**len(scenarios)):
# 0 = don't reveal until the "main chain" looks like it's close to catching up
insta_reveal = strat_id % 2
print 'Testing strategy: %r, insta_reveal: %d', (strategy, insta_reveal)
print 'Testing strategy: %r, insta_reveal: %d' % (strategy, insta_reveal)
pubchain = Chain(randao=random.randrange(10**20))
@ -167,5 +170,11 @@ for strat_id in range(2**len(scenarios)):
pass
# print 'Score deltas: me %.2f them %.2f, time delta %d' % (pubchain.me - old_me, pubchain.them - old_them, time - old_time)
gf = (pubchain.them - 100000. * (100 - attacker_share) / 100) / (pubchain.me - 100000 * attacker_share / 100)
my_loss = 100000 * attacker_share / 100 - pubchain.me
their_loss = 100000 * (100 - attacker_share) / 100 - pubchain.them
my_total_loss += my_loss
their_total_loss += their_loss
gf = their_loss / my_loss if my_loss > 0 else 999.99
print 'My revenue: %d, their revenue: %d, griefing factor %.2f' % (pubchain.me, pubchain.them, gf)
print 'Total griefing factor: %.2f' % (their_total_loss / my_total_loss)

View File

@ -17,8 +17,8 @@ b12 = FQ12([3] + [0] * 11)
# Generator for curve over FQ
G1 = (FQ(1), FQ(2))
# Generator for twisted curve over FQ2
G2 = (FQ2([16260673061341949275257563295988632869519996389676903622179081103440260644990L, 11559732032986387107991004021392285783925812861821192530917403151452391805634L]),
FQ2([15530828784031078730107954109694902500959150953518636601196686752670329677317L, 4082367875863433681332203403145435568316851327593401208105741076214120093531L]))
G2 = (FQ2([16260673061341949275257563295988632869519996389676903622179081103440260644990, 11559732032986387107991004021392285783925812861821192530917403151452391805634]),
FQ2([15530828784031078730107954109694902500959150953518636601196686752670329677317, 4082367875863433681332203403145435568316851327593401208105741076214120093531]))
# Check that a point is on the curve defined by y**2 == x**3 + b
def is_on_curve(pt, b):
@ -62,9 +62,9 @@ def multiply(pt, n):
elif n == 1:
return pt
elif not n % 2:
return multiply(double(pt), n / 2)
return multiply(double(pt), n // 2)
else:
return add(multiply(double(pt), int(n / 2)), pt)
return add(multiply(double(pt), int(n // 2)), pt)
# Check that the G1 curve works fine
assert add(add(double(G1), G1), G1) == double(double(G1))

View File

@ -1,6 +1,12 @@
import sys
sys.setrecursionlimit(10000)
# python3 compatibility
try:
foo = long
except:
long = int
# The prime modulus of the field
field_modulus = 21888242871839275222246405745257275088696311157297823662689037894645226208583
# See, it's prime!
@ -61,20 +67,26 @@ class FQ():
assert isinstance(on, (int, long))
return FQ(self.n * inv(on, field_modulus) % field_modulus)
def __truediv__(self, other):
return self.__div__(other)
def __rdiv__(self, other):
on = other.n if isinstance(other, FQ) else other
assert isinstance(on, (int, long)), on
return FQ(inv(self.n, field_modulus) * on % field_modulus)
def __rtruediv__(self, other):
return self.__rdiv__(other)
def __pow__(self, other):
if other == 0:
return FQ(1)
elif other == 1:
return FQ(self.n)
elif other % 2 == 0:
return (self * self) ** (other / 2)
return (self * self) ** (other // 2)
else:
return ((self * self) ** int(other / 2)) * self
return ((self * self) ** int(other // 2)) * self
def __eq__(self, other):
if isinstance(other, FQ):
@ -166,15 +178,18 @@ class FQP():
assert isinstance(other, self.__class__)
return self * other.inv()
def __truediv__(self, other):
return self.__div__(other)
def __pow__(self, other):
if other == 0:
return self.__class__([1] + [0] * (self.degree - 1))
elif other == 1:
return self.__class__(self.coeffs)
elif other % 2 == 0:
return (self * self) ** (other / 2)
return (self * self) ** (other // 2)
else:
return ((self * self) ** int(other / 2)) * self
return ((self * self) ** int(other // 2)) * self
# Extended euclidean algorithm used to find the modular inverse
def inv(self):

View File

@ -62,7 +62,7 @@ def miller_loop(Q, P):
R = add(R, Q1)
f = f * linefunc(R, nQ2, P)
# R = add(R, nQ2) This line is in many specifications but it technically does nothing
return f ** ((field_modulus ** 12 - 1) / curve_order)
return f ** ((field_modulus ** 12 - 1) // curve_order)
# Pairing computation
def pairing(Q, P):

View File

@ -3,22 +3,22 @@ from bn128_pairing import pairing, neg, G2, G1, multiply, FQ12, curve_order
p1 = pairing(G2, G1)
pn1 = pairing(G2, neg(G1))
assert p1 * pn1 == FQ12.one()
print 'Pairing check against negative in G1 passed'
print('Pairing check against negative in G1 passed')
np1 = pairing(neg(G2), G1)
assert p1 * np1 == FQ12.one()
assert pn1 == np1
print 'Pairing check against negative in G2 passed'
print('Pairing check against negative in G2 passed')
assert p1 ** curve_order == FQ12.one()
print 'Pairing output has correct order'
print('Pairing output has correct order')
p2 = pairing(G2, multiply(G1, 2))
assert p1 * p1 == p2
print 'Pairing bilinearity in G1 passed'
print('Pairing bilinearity in G1 passed')
assert p1 != p2 and p1 != np1 and p2 != np1
print 'Pairing is non-degenerate'
print('Pairing is non-degenerate')
po2 = pairing(multiply(G2, 2), G1)
assert p1 * p1 == po2
print 'Pairing bilinearity in G2 passed'
print('Pairing bilinearity in G2 passed')
p3 = pairing(multiply(G2, 27), multiply(G1, 37))
po3 = pairing(G2, multiply(G1, 999))
assert p3 == po3
print 'Composite check passed'
print('Composite check passed')