create method
Returns a new array of secret shares (encoding x,y pairs as Base64 or Hex strings) created by Shamir's Secret Sharing Algorithm requiring a minimum number of share to recreate, of length shares, from the input secret raw as a string.
Implementation
List<String> create(int minimum, int shares, String secret, bool isBase64) {
List<String> rs = [];
// Verify minimum isn't greater than shares; there is no way to recreate
// the original polynomial in our current setup, therefore it doesn't make
// sense to generate fewer shares than are needed to reconstruct the secret.
if (minimum <= 0 || shares <= 0) {
throw new Exception("minimum or shares is invalid");
}
if (minimum > shares) {
throw new Exception("cannot require more shares then existing");
}
if (secret.isEmpty) {
throw new Exception("secret is NULL or empty");
}
// Convert the secret to its respective 256-bit BigInteger representation
List<BigInt> secrets = splitSecretToBigInt(secret);
// List of currently used numbers in the polynomial
List<BigInt> numbers = [];
numbers.add(BigInt.zero);
// Create the polynomial of degree (minimum - 1); that is, the highest
// order term is (minimum-1), though as there is a constant term with
// order 0, there are (minimum) number of coefficients.
//
// However, the polynomial object is a 2d array, because we are constructing
// a different polynomial for each part of the secret
//
// polynomial[parts][minimum]
// BigInt[][] polynomial = new BigInt[secrets.size()][minimum];
var polynomial =
List<List<BigInt>>.generate(secrets.length, (i) => List<BigInt>.generate(minimum, (j) => BigInt.zero));
for (int i = 0; i < secrets.length; i++) {
polynomial[i][0] = secrets[i];
for (int j = 1; j < minimum; j++) {
// Each coefficient should be unique
BigInt number = randomNumber();
while (inNumbers(numbers, number)) {
number = randomNumber();
}
numbers.add(number);
polynomial[i][j] = number;
}
}
// Create the points object; this holds the (x, y) points of each share.
// Again, because secrets is an array, each share could have multiple parts
// over which we are computing Shamir's Algorithm. The last dimension is
// always two, as it is storing an x, y pair of points.
//
// For every share...
for (int i = 0; i < shares; i++) {
String s = "";
// and every part of the secret...
for (int j = 0; j < secrets.length; j++) {
// generate a new x-coordinate
BigInt x = randomNumber();
while (inNumbers(numbers, x)) {
x = randomNumber();
}
numbers.add(x);
// and evaluate the polynomial at that point
BigInt y = evaluatePolynomial(polynomial, j, x);
if (isBase64) {
// encode to Base64.
s += toBase64Url(x);
s += toBase64Url(y);
} else {
// encode to Hex.
s += toHex(x);
s += toHex(y);
}
}
rs.add(s);
}
return rs;
}