PastaSqrtTables<F extends PastaFieldElement<F>> constructor

PastaSqrtTables<F extends PastaFieldElement<F>>({
  1. required int hashXor,
  2. required int hashMod,
  3. required F rootOfUnity,
  4. required F one,
})

Implementation

factory PastaSqrtTables({
  required int hashXor,
  required int hashMod,
  required F rootOfUnity,
  required F one,
}) {
  int getHash(F x) {
    final lower32 = x.getLower32(); // returns int (0..2^32-1)
    final hashed = (lower32 ^ hashXor); // xor salt
    return hashed % hashMod; // mod table size
  }

  F gi = rootOfUnity;

  List<List<F>> gtab = [];

  for (int k = 0; k < 4; k++) {
    // Compute the 256-element table for this level.
    List<F> table = [];
    F acc = one;

    for (int i = 0; i < 256; i++) {
      table.add(acc);
      acc = acc * gi;
    }

    // Update gi = table[255] * gi
    gi = table[255] * gi;

    gtab.add(table);
  }

  List<F> gtab0 = gtab[0];
  List<F> gtab1 = gtab[1];
  List<F> gtab2 = gtab[2];
  List<F> gtab3 = gtab[3];

  //
  // Build inverse table for g3
  //
  List<int> inv = List.filled(hashMod, 1);

  for (int j = 0; j < gtab3.length; j++) {
    int hash = getHash(gtab3[j]);

    if (inv[hash] != 1) {
      throw CryptoException.failed(
        "PastaSqrtTables",
        reason: "hash collision in sqrt table",
      );
    }

    inv[hash] = (256 - j) & 0xFF;
  }
  gtab3 = gtab3.sublist(0, 129);
  return PastaSqrtTables<F>._(
    inv: inv,
    rootOfUnity: rootOfUnity,
    hashMod: hashMod,
    hashXor: hashXor,
    g0: gtab0,
    g1: gtab1,
    g2: gtab2,
    g3: gtab3,
  );
}