Grain<F extends PastaFieldElement<F>> constructor

Grain<F extends PastaFieldElement<F>>({
  1. required SboxType sbox,
  2. required int t,
  3. required int rF,
  4. required int rP,
  5. required F fromBytes(
    1. List<int> bytes
    ),
  6. int length = 80,
})

Equivalent to the Rust constructor new(...)

Implementation

factory Grain({
  required SboxType sbox,
  required int t,
  required int rF,
  required int rP,
  required F Function(List<int> bytes) fromBytes,
  int length = 80,
}) {
  List<bool> state = List<bool>.filled(length, true);
  void setBits(int offset, int len, int value) {
    for (int i = 0; i < len; i++) {
      int bit = (value >> i) & 1;
      state[offset + (len - 1 - i)] = bit == 1;
    }
  }

  final numBits = PallasFPConst.numBits;

  // Equivalent to Rust:
  // set_bits(0, 2, FieldType::PrimeOrder.tag() as u16);
  setBits(0, 2, FieldType.primeOrder.tag);

  // set_bits(2, 4, sbox.tag() as u16);
  setBits(2, 4, sbox.tag);

  // set_bits(6, 12, F::NUM_BITS as u16);
  setBits(6, 12, numBits);

  // set_bits(18, 12, t);
  setBits(18, 12, t);

  // set_bits(30, 10, r_f);
  setBits(30, 10, rF);

  // set_bits(40, 10, r_p);
  setBits(40, 10, rP);
  final grain = Grain<F>._(
    state: state,
    nextBit: length,
    numBits: numBits,
    fromBytes: fromBytes,
  );

  // discard first 160 bits (20 × 8 bits)
  for (int i = 0; i < 20; i++) {
    grain._loadNext8Bits();
    grain._nextBit = length; // identical to Rust: grain.next_bit = STATE;
  }

  return grain;
}