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