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