@@ -107,3 +107,72 @@ def mod_inverse(self, number):
107
107
if number < 0 :
108
108
remainder *= - 1
109
109
return (self .prime + remainder ) % self .prime
110
+
111
+
112
+ def shares_to_x_y (self ,shares ):
113
+ x = []
114
+ y = []
115
+ # must be: len(shares[0])//88 == len(shares[0])/88
116
+ for i in range (len (shares [0 ])// 88 ):
117
+ part_x = []
118
+ part_y = []
119
+ for share in shares :
120
+ part_x .append (self .from_base64 (share [88 * i + 0 :88 * i + 44 ]))
121
+ part_y .append (self .from_base64 (share [88 * i + 44 :88 * i + 88 ]))
122
+ x .append (tuple (part_x ))
123
+ y .append (tuple (part_y ))
124
+ return x ,y
125
+
126
+ # extended_gcd, divmod, lagrange_interpolate are copied from https://en.wikipedia.org/wiki/Shamir%27s_Secret_Sharing
127
+
128
+ def extended_gcd (self , a , b ):
129
+ """
130
+ Division in integers modulus p means finding the inverse of the
131
+ denominator modulo p and then multiplying the numerator by this
132
+ inverse (Note: inverse of A is B such that A*B % p == 1) this can
133
+ be computed via extended Euclidean algorithm
134
+ http://en.wikipedia.org/wiki/Modular_multiplicative_inverse#Computation
135
+ """
136
+ x = 0
137
+ last_x = 1
138
+ y = 1
139
+ last_y = 0
140
+ while b != 0 :
141
+ quot = a // b
142
+ a , b = b , a % b
143
+ x , last_x = last_x - quot * x , x
144
+ y , last_y = last_y - quot * y , y
145
+ return last_x , last_y
146
+
147
+ def divmod (self , num , den , p ):
148
+ """Compute num / den modulo prime p
149
+
150
+ To explain what this means, the return value will be such that
151
+ the following is true: den * divmod(num, den, p) % p == num
152
+ """
153
+ inv , _ = self .extended_gcd (den , p )
154
+ return num * inv
155
+
156
+ def lagrange_interpolate (self , x , x_s , y_s , p ):
157
+ """
158
+ Find the y-value for the given x, given n (x, y) points;
159
+ k points will define a polynomial of up to kth order.
160
+ """
161
+ k = len (x_s )
162
+ assert k == len (set (x_s )), "points must be distinct"
163
+ def PI (vals ): # upper-case PI -- product of inputs
164
+ accum = 1
165
+ for v in vals :
166
+ accum *= v
167
+ return accum
168
+ nums = [] # avoid inexact division
169
+ dens = []
170
+ for i in range (k ):
171
+ others = list (x_s )
172
+ cur = others .pop (i )
173
+ nums .append (PI (x - o for o in others ))
174
+ dens .append (PI (cur - o for o in others ))
175
+ den = PI (dens )
176
+ num = sum ([self .divmod (nums [i ] * den * y_s [i ] % p , dens [i ], p )
177
+ for i in range (k )])
178
+ return (self .divmod (num , den , p ) + p ) % p
0 commit comments