Added slasher exploit

This commit is contained in:
Vitalik Buterin 2014-09-06 23:00:50 -04:00
parent bf111a8bd9
commit 6978ce98d4
2 changed files with 77 additions and 0 deletions

View File

@ -94,6 +94,40 @@ class Galois:
def __repr__(self):
return repr(self.val)
# Modular division class
def mkModuloClass(n):
if pow(2, n, n) != 2:
raise Exception("n must be prime!")
class Mod:
val = 0
def __init__(self, val):
self.val = val.val if isinstance(
self.val, self.__class__) else val
def __add__(self, other):
return self.__class__((self.val + other.val) % n)
def __mul__(self, other):
return self.__class__((self.val * other.val) % n)
def __sub__(self, other):
return self.__class__((self.val - other.val) % n)
def __div__(self, other):
return self.__class__((self.val * other.val ** (n-2)) % n)
def __int__(self):
return self.val
def __repr__(self):
return repr(self.val)
return Mod
# Evaluates a polynomial in little-endian form, eg. x^2 + 3x + 2 = [2, 3, 1]
# (normally I hate little-endian, but in this case dealing with polynomials
# it's justified, since you get the nice property that p[n] is the nth degree

View File

@ -0,0 +1,43 @@
def fac(n): return 1 if n==0 else n * fac(n-1)
def choose(n,k): return fac(n) / fac(k) / fac(n-k)
def prob(n,k,p): return choose(n,k) * p ** k * (1-p) ** (n-k)
def prob_lt(n,k,p): return sum([prob(n,i,p) for i in range(p)])
SIGS = 30
ACTUALSIGS = 10
POWRETURN = 0.03
POSRETURN = 0.01
# Expected number of signatures on a block
def ev(pos):
return SIGS * pos
# Chance you have at least k sigs
def at_least_k(pos, k):
return sum([prob(SIGS, i, pos) for i in range(k, SIGS + 1)])
# Expected number of signatures on a block filtering all <k
def ev_atleast_k(pos, k):
total, subprob = 0, 0
for i in range(k, SIGS + 1):
p = prob(SIGS, i, pos)
subprob += p
total += i * p
return total / subprob
def normal_mining_return(pow, pos):
return pow * POWRETURN + ev(pos) * POSRETURN / ACTUALSIGS
def attack_mining_return(pow, pos, k):
powtotal, postotal, subprob = 0, 0, 0
# Case 1: mined PoW block, PoS at least k instances
case_1_prob = pow * at_least_k(pos, k)
subprob += case_1_prob
postotal += case_1_prob * ev_atleast_k(pos, k) * POSRETURN / ACTUALSIGS
powtotal += case_1_prob * POWRETURN
# Case 2: mined PoW block, PoS less than k: discard
# Case 3: others mined PoW block
subprob += (1 - pow)
postotal += (1 - pow) * ev(pos) * POSRETURN / ACTUALSIGS
return powtotal / subprob + postotal / subprob