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)); }
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]); }
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)); }
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)); }
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); } }
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)); } }
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); }
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") // } }
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) // } } } } }
public override byte[] Combine(byte[] secretCrypt) { return(HashiCorpShamir.Combine(Shares.ToArray())); }
// 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); }
public void TestPolynomial_Random() { var p = HashiCorpShamir.MakePolynomial(42, 2); Assert.Equal(42, p.Coefficients[0]); }
public void TestField_Add() { Assert.Equal(0, HashiCorpShamir.Add(16, 16)); Assert.Equal(7, HashiCorpShamir.Add(3, 4)); }