cryptokemenc function

int cryptokemenc(
  1. Uint8List c,
  2. Uint8List ss,
  3. Uint8List pk
)

Encapsulates a shared secret ss using public key pk and produces ciphertext c.

The algorithm generates a random message m of length KYBER_SYMBYTES, and then computes mh = shake128(m, KYBER_SYMBYTES). The key K = shake128(mh || pk, KYBER_SYMBYTES) is then generated, and the coins coins = shake(K || mh, KYBER_SYMBYTES) are computed. The ciphertext c is then computed as c = indcpaenc(mh, pk, coins). Finally, the shared secret ss = shake(K || c, KYBER_SSBYTES) is computed and returned.

Implementation

int cryptokemenc(Uint8List c, Uint8List ss, Uint8List pk) {
  // m random
  Uint8List m = randombytes(KYBER_SYMBYTES);

  // hash(m)
  Uint8List mh = shake128(m, KYBER_SYMBYTES);

  // hash(mh || pk)
  Uint8List kpInput = Uint8List(KYBER_SYMBYTES + KYBER_PUBLICKEYBYTES);
  kpInput.setRange(0, KYBER_SYMBYTES, mh);
  kpInput.setRange(KYBER_SYMBYTES, KYBER_SYMBYTES + KYBER_PUBLICKEYBYTES, pk);
  Uint8List K = shake128(kpInput, KYBER_SYMBYTES);

  // coins = shake(K || mh)
  Uint8List coinsInput = Uint8List(KYBER_SYMBYTES + KYBER_SYMBYTES);
  coinsInput.setRange(0, KYBER_SYMBYTES, K);
  coinsInput.setRange(KYBER_SYMBYTES, 2 * KYBER_SYMBYTES, mh);
  Uint8List coins = shake128(coinsInput, KYBER_SYMBYTES);

  // c = indcpaenc(mh, pk, coins)
  indcpaenc(c, mh, pk, coins);

  // ss = shake(K || c)
  Uint8List ssInput = Uint8List(KYBER_SYMBYTES + KYBER_CIPHERTEXTBYTES);
  ssInput.setRange(0, KYBER_SYMBYTES, K);
  ssInput.setRange(KYBER_SYMBYTES, KYBER_SYMBYTES + KYBER_CIPHERTEXTBYTES, c);
  Uint8List out = shake128(ssInput, KYBER_SSBYTES);
  ss.setAll(0, out);

  return 0;
}