A member of a key share collection.
Inheritance: Secret
Esempio n. 1
0
 /// <summary>
 /// Recreate a secret from the specified shares.
 /// </summary>
 /// <param name="Shares">The shares to be recombined.</param>
 public Secret(KeyShare[] Shares) {
     this.Key = Combine(Shares);
     }
Esempio n. 2
0
        /// <summary>
        /// Recreate a secret from shares specified as Base32 encoded strings.
        /// </summary>
        /// <param name="Shares">The shares to be recombined.</param>
        public Secret (string[] Shares) {

            var KeyShares = new KeyShare[Shares.Length];

            int i = 0;
            foreach (var Share in Shares) {
                var Bytes = BaseConvert.FromBase32String(Share);
                KeyShares[i++] = new KeyShare(Bytes);
                }

            this.Key = Combine(KeyShares);
            }
Esempio n. 3
0
        static byte[] CombineNK(KeyShare[] Shares) {
            
            var Threshold = Shares[0].Threshold;
            if (Shares.Length < Threshold) throw new Throw("Not Enough Shares");

            var Modulus = BigInteger.Pow(2, 129) - 25;
            BigInteger Accum = 0;

            //Console.WriteLine("Modulus = {0} ", Modulus);


            for (var Formula = 0; Formula < Threshold; Formula++) {

                var Value = Shares[Formula].Value;
                //Console.WriteLine("Value = {0} ", Value);

                BigInteger Numerator = 1, Denominator = 1;
                for (var Count = 0; Count < Threshold; Count++) {
                    if (Formula == Count) continue;  // If not the same value
                    var Start = Shares[Formula].Index;
                    var Next = Shares[Count].Index;

                    Numerator = (Numerator * -Next) % Modulus;
                    Denominator = (Denominator * (Start - Next)) % Modulus;
                    }

                var InvDenominator = ModInverse(Denominator, Modulus);

                //Console.WriteLine("   Numerator = {0}", Numerator);
                //Console.WriteLine("   Denominator = {0}", Denominator);
                //Console.WriteLine("   InvDenominator = {0}", InvDenominator);

                Accum = (Modulus + Modulus + Accum + (Value * Numerator * InvDenominator)) % Modulus;
                if (Accum < 0) {
                    //Console.WriteLine("Accum = {0}\n", Accum);
                    }
                }

            //Console.WriteLine("Accum = {0} ", Accum);
            return GetBytes (Accum);
            }
Esempio n. 4
0
        static byte[] CombineN(KeyShare[] Shares) {
            var KeyBytes = Shares[0].Key.Length;
            byte[] Result = new byte[KeyBytes - 1];

            foreach (var Share in Shares) {
                ArrayXOR1(Result, Share.Key);
                }

            return Result;
            }
Esempio n. 5
0
        static byte[] Combine(KeyShare[] Shares) {
            //var KeyBytes = 16; //Shares[0].Key.Length;
            var Threshold = Shares[0].Threshold;
            foreach (var Share in Shares) {
                //if (Share.Key.Length != KeyBytes) {
                //    throw new Exception("Keys must be same length");
                //    }
                if (Share.Threshold != Threshold) {
                    throw new Throw("Keys must have same threshold");
                    }
                }

            if (Shares[0].Index == 16) {
                return CombineN(Shares);
                }
            else {
                return CombineNK(Shares);
                }

            }
Esempio n. 6
0
        /// <summary>
        /// Create a set of N key shares with a quorum of N.
        /// </summary>
        /// <returns>The key shares created.</returns> 
        public KeyShare[] Split(int N) {
            var KeyShares = new KeyShare[N];
            var Threshold = (16 * N) + 15;

            var XOR = new byte[KeyBytes];
            Array.Copy(Key, XOR, KeyBytes);
            for (int i = 0; i < N - 1; i++) {
                var Bytes = CryptoCatalog.GetBytes(KeyBytes);
                KeyShares[i] = new KeyShare(Threshold, Bytes);
                ArrayXOR(XOR, Bytes);
                }
            KeyShares[N - 1] = new KeyShare(Threshold, XOR);

            return KeyShares;
            }
Esempio n. 7
0
        /// <summary>
        /// Create a set of N key shares with a quorum of K.
        /// </summary>
        /// <param name="N">Number of key shares to create (max is 32).</param>
        /// <param name="K">Quorum of key shares required to reconstruct the secret.</param>
        /// <returns>The key shares created.</returns>
        public KeyShare[] Split(int N, int K) {
            if (K > N) throw new Throw("Quorum can't exceed shares");
            if (K < 2) throw new Throw("Quorum must be at least 2");
            if (N < 2) throw new Throw("Shares must be at least 2");
            if (N > 15) throw new Throw("Too many shares");

            if (N == K) return Split(N);

            if (K > 15) throw new Throw("Degree too high");

            var PolyNomial = new BigInteger[K];
            PolyNomial[0] = MakePositive(Key);
            //Console.WriteLine("Key = {0} ", PolyNomial[0]);


            for (int i = 1; i < K; i++) {
                var Random = CryptoCatalog.GetBytes(KeyBytes);
                PolyNomial[i] = MakePositive(Random);
                }

            if (KeyBits != 128) throw new Throw("Only 128 bit keys supported right now");

            // 2^129-25 is a pseudo Mersene prime
            var Modulus = BigInteger.Pow(2, 129) - 25;
            //Console.WriteLine("Modulus = {0} ", Modulus);

            var KeyShares = new KeyShare[N];
            for (int i = 0; i < N; i++) {
                var D = PolyMod(i + 1, PolyNomial, Modulus);
                KeyShares[i] = new KeyShare((K * 16) + i, D);

                //Console.WriteLine("Share {0} = {1}", i, D);
                }

            return KeyShares;
            }