コード例 #1
0
        public void TestCombine_invalid()
        {
            // Not enough parts
            Assert.ThrowsAny <ArgumentException>(
                () => HashiCorpShamir.Combine(null));

            // Mis-match in length
            var parts = new byte[][]
            {
                Encoding.UTF8.GetBytes("foo"),
                Encoding.UTF8.GetBytes("ba"),
            };

            Assert.ThrowsAny <ArgumentException>(
                () => HashiCorpShamir.Combine(parts));

            //Too short
            parts = new byte[][]
            {
                Encoding.UTF8.GetBytes("f"),
                Encoding.UTF8.GetBytes("b"),
            };
            Assert.ThrowsAny <ArgumentException>(
                () => HashiCorpShamir.Combine(parts));

            parts = new byte[][]
            {
                Encoding.UTF8.GetBytes("foo"),
                Encoding.UTF8.GetBytes("foo"),
            };
            Assert.ThrowsAny <InvalidOperationException>(
                () => HashiCorpShamir.Combine(parts));
        }
コード例 #2
0
        public override byte[] Split(byte[] secretClear, int shareCount, int threshold)
        {
            Shares = HashiCorpShamir.Split(secretClear, shareCount, threshold);

            // All encoded data is contained within the encoded shares,
            // so there is no transformed form of the secret to return
            return(new byte[0]);
        }
コード例 #3
0
        public void TestField_Divide()
        {
            Assert.Equal(0, HashiCorpShamir.Div(0, 7));

            Assert.Equal(1, HashiCorpShamir.Div(3, 3));

            Assert.Equal(2, HashiCorpShamir.Div(6, 3));
        }
コード例 #4
0
        public void TestField_Mult()
        {
            Assert.Equal(9, HashiCorpShamir.Mult(3, 7));

            Assert.Equal(0, HashiCorpShamir.Mult(3, 0));

            Assert.Equal(0, HashiCorpShamir.Mult(0, 3));
        }
コード例 #5
0
        public void TestSplit()
        {
            var secret = Encoding.UTF8.GetBytes("test");

            var ret = HashiCorpShamir.Split(secret, 5, 3);

            Assert.Equal(5, ret.Length);

            foreach (var share in ret)
            {
                Assert.Equal(share.Length, secret.Length + 1);
            }
        }
コード例 #6
0
        public void TestInterpolate_Rand()
        {
            for (int i = 0; i < 256; i++)
            {
                var p = HashiCorpShamir.MakePolynomial((byte)i, 2);

                var x_vals = new byte[] { 1, 2, 3 };
                var y_vals = new byte[] { p.Evaluate(1), p.Evaluate(2), p.Evaluate(3) };

                // out := interpolatePolynomial(x_vals, y_vals, 0)
                // if out != uint8(i) {
                //     t.Fatalf("Bad: %v %d", out, i)
                // }

                Assert.Equal((byte)i,
                             HashiCorpShamir.InterpolatePolynomial(x_vals, y_vals, 0));
            }
        }
コード例 #7
0
        public void TestPolynomial_Eval()
        {
            var p = HashiCorpShamir.MakePolynomial(42, 1);

            Assert.Equal(42, p.Evaluate(0));

            // out := p.evaluate(1)
            // exp := add(42, mult(1, p.coefficients[1]))
            // if out != exp {
            //     t.Fatalf("bad: %v %v %v", out, exp, p.coefficients)
            // }

            var ret = p.Evaluate(1);
            var exp = HashiCorpShamir.Add(42,
                                          HashiCorpShamir.Mult(1, p.Coefficients[1]));

            Assert.Equal(ret, exp);
        }
コード例 #8
0
        public void TestSplit_invalid()
        {
            var secret = Encoding.UTF8.GetBytes("test");

            Assert.ThrowsAny <ArgumentException>(
                () => HashiCorpShamir.Split(secret, 0, 0));

            Assert.ThrowsAny <ArgumentException>(
                () => HashiCorpShamir.Split(secret, 2, 3));

            Assert.ThrowsAny <ArgumentException>(
                () => HashiCorpShamir.Split(secret, 1000, 3));

            Assert.ThrowsAny <ArgumentException>(
                () => HashiCorpShamir.Split(secret, 10, 1));

            Assert.ThrowsAny <ArgumentException>(
                () => HashiCorpShamir.Split(new byte[0], 3, 2));

            Assert.ThrowsAny <ArgumentException>(
                () => HashiCorpShamir.Split(null, 3, 2));

            // if _, err := Split(secret, 0, 0); err == nil {
            //     t.Fatalf("expect error")
            // }

            // if _, err := Split(secret, 2, 3); err == nil {
            //     t.Fatalf("expect error")
            // }

            // if _, err := Split(secret, 1000, 3); err == nil {
            //     t.Fatalf("expect error")
            // }

            // if _, err := Split(secret, 10, 1); err == nil {
            //     t.Fatalf("expect error")
            // }

            // if _, err := Split(nil, 3, 2); err == nil {
            //     t.Fatalf("expect error")
            // }
        }
コード例 #9
0
        public void TestCombine()
        {
            var secret = Encoding.UTF8.GetBytes("test");

            var ret = HashiCorpShamir.Split(secret, 5, 3);

            // There is 5*4*3 possible choices,
            // we will just brute force try them all
            for (int i = 0; i < 5; i++)
            {
                for (var j = 0; j < 5; j++)
                {
                    if (j == i)
                    {
                        continue;
                    }

                    for (var k = 0; k < 5; k++)
                    {
                        if (k == i || k == j)
                        {
                            continue;
                        }

                        var parts  = new byte[][] { ret[i], ret[j], ret[k] };
                        var recomb = HashiCorpShamir.Combine(parts);

                        Assert.Equal(recomb, secret);
                        // if !bytes.Equal(recomb, secret) {
                        //     t.Errorf("parts: (i:%d, j:%d, k:%d) %v", i, j, k, parts)
                        //     t.Fatalf("bad: %v %v", recomb, secret)
                        // }
                    }
                }
            }
        }
コード例 #10
0
 public override byte[] Combine(byte[] secretCrypt)
 {
     return(HashiCorpShamir.Combine(Shares.ToArray()));
 }
コード例 #11
0
        // Combine is used to reverse a Split and reconstruct a secret
        // once a `threshold` number of parts are available.
        public static byte[] Combine(byte[][] parts)
        {
            // Verify enough parts provided
            if ((parts?.Length).GetValueOrDefault() < 2)
            {
                throw new ArgumentOutOfRangeException(nameof(parts),
                                                      "less than two parts cannot be used to reconstruct the secret");
            }

            // Verify the parts are all the same length
            var firstPartLen = parts[0].Length;

            if (firstPartLen < 2)
            {
                throw new ArgumentException(nameof(parts),
                                            "parts must be at least two bytes");
            }

            for (int i = 1; i < parts.Length; i++)
            {
                if (parts[i].Length != firstPartLen)
                {
                    throw new ArgumentException(nameof(parts),
                                                "all parts must be the same length");
                }
            }

            // Create a buffer to store the reconstructed secret
            var secret = new byte[firstPartLen - 1];

            // Buffer to store the samples
            var x_samples = new byte[parts.Length];
            var y_samples = new byte[parts.Length];

            // Set the x value for each sample and ensure no x_sample values are the same,
            // otherwise div() can be unhappy
            var checkMap = new Dictionary <byte, bool>();

            for (int i = 0; i < parts.Length; i++)
            {
                var part = parts[i];
                var samp = part[firstPartLen - 1];
                if (checkMap.ContainsKey(samp))
                {
                    throw new InvalidOperationException("duplicate part detected");
                }

                checkMap[samp] = true;
                x_samples[i]   = samp;
            }

            // Reconstruct each byte
            for (int idx = 0; idx < secret.Length; idx++)
            {
                // Set the y value for each sample
                for (int i = 0; i < parts.Length; i++)
                {
                    var part = parts[i];
                    y_samples[i] = part[idx];
                }

                // Interpolte the polynomial and compute the value at 0
                var val = HashiCorpShamir.InterpolatePolynomial(x_samples, y_samples, 0);

                // Evaluate the 0th value to get the intercept
                secret[idx] = val;
            }
            return(secret);
        }
コード例 #12
0
        public void TestPolynomial_Random()
        {
            var p = HashiCorpShamir.MakePolynomial(42, 2);

            Assert.Equal(42, p.Coefficients[0]);
        }
コード例 #13
0
        public void TestField_Add()
        {
            Assert.Equal(0, HashiCorpShamir.Add(16, 16));

            Assert.Equal(7, HashiCorpShamir.Add(3, 4));
        }