cryptokemdec function

int cryptokemdec(
  1. Uint8List ss,
  2. Uint8List c,
  3. Uint8List sk
)

Decapsulates the shared secret ss from ciphertext c using private key sk.

The algorithm first extracts the public key pk, hash of pk, and random value z from sk. Then, it computes m' = indcpadec(c, sk), K' = hash(m' || pk), coins' = hash(K' || m'), and c' = indcpaenc(m', pk, coins'). If c' == c, then ss = hash(K' || c), otherwise ss = hash(z || c). The shared secret ss is then returned.

Implementation

int cryptokemdec(Uint8List ss, Uint8List c, Uint8List sk) {
// extract pk, hashPk, z from sk
Uint8List pk = sk.sublist(
    KYBER_SECRETKEYBYTES - KYBER_PUBLICKEYBYTES - KYBER_SYMBYTES,
    KYBER_SECRETKEYBYTES - KYBER_SYMBYTES);
// Uint8List hashPk = sk.sublist(KYBER_SECRETKEYBYTES - KYBER_SYMBYTES, KYBER_SECRETKEYBYTES);
Uint8List z = sk.sublist(KYBER_SECRETKEYBYTES - 2 * KYBER_SYMBYTES,
    KYBER_SECRETKEYBYTES - KYBER_SYMBYTES * 2 + KYBER_SYMBYTES);

// m' = indcpadec(c, sk)
Uint8List mprime = Uint8List(KYBER_SYMBYTES);
indcpadec(mprime, c, sk);

// K' = hash(m' || pk)
Uint8List kpInput = Uint8List(KYBER_SYMBYTES + KYBER_PUBLICKEYBYTES);
kpInput.setRange(0, KYBER_SYMBYTES, mprime);
kpInput.setRange(KYBER_SYMBYTES, KYBER_SYMBYTES + KYBER_PUBLICKEYBYTES, pk);
Uint8List kprime = shake128(kpInput, KYBER_SYMBYTES);

// coins' = hash(K' || m')
Uint8List coinsInput = Uint8List(KYBER_SYMBYTES + KYBER_SYMBYTES);
coinsInput.setRange(0, KYBER_SYMBYTES, kprime);
coinsInput.setRange(KYBER_SYMBYTES, 2 * KYBER_SYMBYTES, mprime);
Uint8List coinsPrime = shake128(coinsInput, KYBER_SYMBYTES);

// c' = indcpaenc(m', pk, coins')
Uint8List cprime = Uint8List(KYBER_CIPHERTEXTBYTES);
indcpaenc(cprime, mprime, pk, coinsPrime);

int fail = verify(c, cprime) ? 0 : 1;

// If fail = 0 => ss = hash(K' || c)
// If fail = 1 => ss = hash(z || c)
Uint8List ssInput = Uint8List(KYBER_SYMBYTES + KYBER_CIPHERTEXTBYTES);
if (fail == 0) {
  ssInput.setRange(0, KYBER_SYMBYTES, kprime);
} else {
  ssInput.setRange(0, KYBER_SYMBYTES, z);
}
ssInput.setRange(KYBER_SYMBYTES, KYBER_SYMBYTES + KYBER_CIPHERTEXTBYTES, c);

Uint8List out = shake128(ssInput, KYBER_SSBYTES);
ss.setAll(0, out);

return 0;
}