keygen method

(SecretKey, Uint8List) keygen({
  1. List<List<int>>? polys,
  2. RandomBytes? randombytes,
})

Generate a key pair (secretKey, verificationKey).

  • polys re-imports an existing key as [f, g, F, G] (used to load a key produced elsewhere); when null a fresh NTRU key is generated.
  • randombytes makes generation reproducible (defaults to secure).

Implementation

(SecretKey, Uint8List) keygen({
  List<List<int>>? polys,
  RandomBytes? randombytes,
}) {
  final List<int> f, g, bigF, bigG;
  if (polys == null) {
    final keys = ntruGen(param.n, randombytes: randombytes);
    f = keys.f;
    g = keys.g;
    bigF = keys.bigF;
    bigG = keys.bigG;
  } else {
    f = List<int>.of(polys[0]);
    g = List<int>.of(polys[1]);
    bigF = List<int>.of(polys[2]);
    bigG = List<int>.of(polys[3]);
  }

  final negF = [for (final e in f) -e];
  final negBigF = [for (final e in bigF) -e];

  // Lattice basis B0 = [[g, -f], [G, -F]]; its Gram matrix and the FFTs.
  final b0 = <List<List<int>>>[
    [g, negF],
    [bigG, negBigF],
  ];
  final g0 = gram(b0);
  final g0Fft = [
    [FalconFFT.fft(g0[0][0]), FalconFFT.fft(g0[0][1])],
    [FalconFFT.fft(g0[1][0]), FalconFFT.fft(g0[1][1])],
  ];
  final tFft = ffldlFft(g0Fft);
  normalizeTree(tFft, param.sigma);

  final b0Fft = [
    [FalconFFT.fft(g), FalconFFT.fft(negF)],
    [FalconFFT.fft(bigG), FalconFFT.fft(negBigF)],
  ];

  // Public key h such that h*f = g mod (Phi, q).
  final fq = [for (final e in f) e % falconQ];
  final gq = [for (final e in g) e % falconQ];
  final h = divZq(gq, fq);
  final vk = serializePoly(h);

  return (SecretKey(param, f, g, bigF, bigG, b0Fft, tFft), vk);
}