create method

List<String> create(
  1. int minimum,
  2. int shares,
  3. String secret,
  4. bool isBase64,
)

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;
}