Made pairing impl python3-friendly
This commit is contained in:
parent
2d1dd0227b
commit
00b990d219
|
@ -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)
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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')
|
||||
|
|
Loading…
Reference in New Issue