-
Notifications
You must be signed in to change notification settings - Fork 7
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
function to add new shares to a set of existing ones #2
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -69,3 +69,30 @@ def combine(self, shares): | |
secret[part_index] = (secret[part_index] + working) % self.util.prime | ||
|
||
return self.util.merge_ints(secret) | ||
|
||
def add_share(self, shares): | ||
# The "raw" secret is padded with \x00 and split into 32 char (64 hex) chunks: for each part there will be a polynomial. | ||
# The result of 'create' still has "shares" entries, but each is a \sum_i^parts x_i+y_i. | ||
# Reconstruct points on the polynomial(s) from the shares | ||
x,y=self.util.shares_to_x_y(shares) | ||
|
||
# Initialize known numbers | ||
numbers = [] | ||
for parts in x: | ||
numbers.extend(parts) | ||
|
||
# For each polynomial, interpolate another point | ||
new_share = "" | ||
for pol_nr in range(len(x)): | ||
value = self.util.random() | ||
while value in numbers: | ||
value = self.util.random() | ||
numbers.append(value) | ||
|
||
y_interpolated = self.util.lagrange_interpolate(value,x[pol_nr],y[pol_nr],self.util.prime) | ||
|
||
new_share += self.util.to_base64(value) | ||
new_share += self.util.to_base64(y_interpolated) | ||
|
||
shares.append(new_share) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not return just the |
||
return shares |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -107,3 +107,72 @@ def mod_inverse(self, number): | |||||||||||||||||||||||||||
if number < 0: | ||||||||||||||||||||||||||||
remainder *= -1 | ||||||||||||||||||||||||||||
return (self.prime + remainder) % self.prime | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
def shares_to_x_y(self,shares): | ||||||||||||||||||||||||||||
x = [] | ||||||||||||||||||||||||||||
y = [] | ||||||||||||||||||||||||||||
# must be: len(shares[0])//88 == len(shares[0])/88 | ||||||||||||||||||||||||||||
for i in range(len(shares[0])//88): | ||||||||||||||||||||||||||||
part_x = [] | ||||||||||||||||||||||||||||
part_y = [] | ||||||||||||||||||||||||||||
for share in shares: | ||||||||||||||||||||||||||||
part_x.append(self.from_base64(share[88*i+0:88*i+44])) | ||||||||||||||||||||||||||||
part_y.append(self.from_base64(share[88*i+44:88*i+88])) | ||||||||||||||||||||||||||||
x.append(tuple(part_x)) | ||||||||||||||||||||||||||||
y.append(tuple(part_y)) | ||||||||||||||||||||||||||||
return x,y | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
# extended_gcd, divmod, lagrange_interpolate are copied from https://en.wikipedia.org/wiki/Shamir%27s_Secret_Sharing | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
def extended_gcd(self, a, b): | ||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could we replace There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure why I didn't do this when I first wrote the code... it has been a while :-) |
||||||||||||||||||||||||||||
""" | ||||||||||||||||||||||||||||
Division in integers modulus p means finding the inverse of the | ||||||||||||||||||||||||||||
denominator modulo p and then multiplying the numerator by this | ||||||||||||||||||||||||||||
inverse (Note: inverse of A is B such that A*B % p == 1) this can | ||||||||||||||||||||||||||||
be computed via extended Euclidean algorithm | ||||||||||||||||||||||||||||
http://en.wikipedia.org/wiki/Modular_multiplicative_inverse#Computation | ||||||||||||||||||||||||||||
""" | ||||||||||||||||||||||||||||
x = 0 | ||||||||||||||||||||||||||||
last_x = 1 | ||||||||||||||||||||||||||||
y = 1 | ||||||||||||||||||||||||||||
last_y = 0 | ||||||||||||||||||||||||||||
while b != 0: | ||||||||||||||||||||||||||||
quot = a // b | ||||||||||||||||||||||||||||
a, b = b, a % b | ||||||||||||||||||||||||||||
x, last_x = last_x - quot * x, x | ||||||||||||||||||||||||||||
y, last_y = last_y - quot * y, y | ||||||||||||||||||||||||||||
return last_x, last_y | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
def divmod(self, num, den, p): | ||||||||||||||||||||||||||||
"""Compute num / den modulo prime p | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
To explain what this means, the return value will be such that | ||||||||||||||||||||||||||||
the following is true: den * divmod(num, den, p) % p == num | ||||||||||||||||||||||||||||
""" | ||||||||||||||||||||||||||||
inv, _ = self.extended_gcd(den, p) | ||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We already have a |
||||||||||||||||||||||||||||
return num * inv | ||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't this be well, |
||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
def lagrange_interpolate(self, x, x_s, y_s, p): | ||||||||||||||||||||||||||||
""" | ||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm fine with this function but we're already doing most of the work in Lines 57 to 69 in f987712
Seems like we should use what's in |
||||||||||||||||||||||||||||
Find the y-value for the given x, given n (x, y) points; | ||||||||||||||||||||||||||||
k points will define a polynomial of up to kth order. | ||||||||||||||||||||||||||||
""" | ||||||||||||||||||||||||||||
k = len(x_s) | ||||||||||||||||||||||||||||
assert k == len(set(x_s)), "points must be distinct" | ||||||||||||||||||||||||||||
def PI(vals): # upper-case PI -- product of inputs | ||||||||||||||||||||||||||||
accum = 1 | ||||||||||||||||||||||||||||
for v in vals: | ||||||||||||||||||||||||||||
accum *= v | ||||||||||||||||||||||||||||
return accum | ||||||||||||||||||||||||||||
nums = [] # avoid inexact division | ||||||||||||||||||||||||||||
dens = [] | ||||||||||||||||||||||||||||
for i in range(k): | ||||||||||||||||||||||||||||
others = list(x_s) | ||||||||||||||||||||||||||||
cur = others.pop(i) | ||||||||||||||||||||||||||||
nums.append(PI(x - o for o in others)) | ||||||||||||||||||||||||||||
dens.append(PI(cur - o for o in others)) | ||||||||||||||||||||||||||||
den = PI(dens) | ||||||||||||||||||||||||||||
num = sum([self.divmod(nums[i] * den * y_s[i] % p, dens[i], p) | ||||||||||||||||||||||||||||
for i in range(k)]) | ||||||||||||||||||||||||||||
return (self.divmod(num, den, p) + p) % p | ||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd keep the newline at the end of the file. :-) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
x, y
-- add a space please. :)