//-------------------------------------------------------------- // Recovering secret by some shades // for theoretical GO TO WIKIPEDIA, reference - shamir secret sharing, lagrange interpolation //-------------------------------------------------------------- private BigInteger deShamir(Dictionary <BigInteger, BigInteger> kv_pairs, BigInteger p) { int k = kv_pairs.Count; BigInteger secret = new BigInteger(0); BigInteger high_part = new BigInteger(1); // high part of lagrange intepolation BigInteger low_part = new BigInteger(1); // low part of lagrange interpolation // first_kv - shade number 1 // second_kv - shade number 2 foreach (KeyValuePair <BigInteger, BigInteger> first_kv in kv_pairs) { foreach (KeyValuePair <BigInteger, BigInteger> second_kv in kv_pairs) { if (first_kv.Key != second_kv.Key) { high_part = high_part * ((-1) * second_kv.Key); // -1 caused that we need x - xj, but our x = 0, that now (-xj) low_part = low_part * (first_kv.Key - second_kv.Key); // calculate low part } } // Lagrange interpolation have division, but we need only integer numbers, so // a * a^(-1) = 1 // but we can make some fun and: // a * a^(-1) = 1 (mod p) // so, when we have modulo, we can change a^(-1) to another number, that give us similar result ^.^ // a * b = 1 (mod p). // b can be calculated by Evklid algorithm in form 'ax + by = gcd(a,b)' (*1) // so we set 2 numbers, a = low_part and b = p, and gets gcd and 2 numbers, x and y. // We know that gcd(prime_number, any_number) = 1, so change (*1) to our rules: // low_part * x + p*y = 1 // In this form y always be the '0' (ave MATH!), so we get // low_part*x = 1 // where x - our (low_part)^(-1) // MAGIIIIIIIIIIC! iVector temp = Evklid(low_part, p); low_part = MathMod(temp.y, p); high_part = MathMod((high_part * low_part), p); // let high part temporary storage all lart of 'li' (see lagrange interpolation) secret += high_part * first_kv.Value; // summ_all( y * li ) high_part = 1; low_part = 1; } secret = MathMod(secret, p); // Let restrict out sercet by out square. return(secret); // Done. You are delicious ^_^ }
public iVector Evklid(BigInteger a, BigInteger b) { iVector u = new iVector(a, 1, 0); iVector v = new iVector(b, 0, 1); iVector T = new iVector(0, 0, 0); BigInteger q = 0; while (v.x != 0) { q = u.x / v.x; T.x = MathMod(u.x, v.x); T.y = u.y - q * v.y; T.z = u.z - q * v.z; u.set(v); // u = v, but we need to CHANGE value, not CHANGE POINTER. v.set(T); // u = v, but we need to CHANGE value, not CHANGE POINTER. } return(u); }
public void set(iVector sec) { this.x = sec.x; this.y = sec.y; this.z = sec.z; }