MastersThesis/PQ_TIIGER_TLS/sal/miracl-ubuntu22-11-04-24/includes/kyber.cpp
2024-04-19 14:16:07 +02:00

813 lines
20 KiB
C++

/*
* Copyright (c) 2012-2020 MIRACL UK Ltd.
*
* This file is part of MIRACL Core
* (see https://github.com/miracl/core).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* Kyber API implementation. Constant time where it matters. Spends nearly all of its time running SHA3. Small.
M.Scott 22/11/2021
*/
#include "kyber.h"
using namespace core;
// parameters for each security level
// K,eta1,eta2,du,dv,shared secret
const int PARAMS_512[6]={2,3,2,10,4,32};
const int PARAMS_768[6]={3,2,2,10,4,32};
const int PARAMS_1024[6]={4,2,2,11,5,32};
/* Start of public domain reference implementation code - taken from https://github.com/pq-crystals/kyber */
const sign16 zetas[128] = {
-1044, -758, -359, -1517, 1493, 1422, 287, 202,
-171, 622, 1577, 182, 962, -1202, -1474, 1468,
573, -1325, 264, 383, -829, 1458, -1602, -130,
-681, 1017, 732, 608, -1542, 411, -205, -1571,
1223, 652, -552, 1015, -1293, 1491, -282, -1544,
516, -8, -320, -666, -1618, -1162, 126, 1469,
-853, -90, -271, 830, 107, -1421, -247, -951,
-398, 961, -1508, -725, 448, -1065, 677, -1275,
-1103, 430, 555, 843, -1251, 871, 1550, 105,
422, 587, 177, -235, -291, -460, 1574, 1653,
-246, 778, 1159, -147, -777, 1483, -602, 1119,
-1590, 644, -872, 349, 418, 329, -156, -75,
817, 1097, 603, 610, 1322, -1285, -1465, 384,
-1215, -136, 1218, -1335, -874, 220, -1187, -1659,
-1185, -1530, -1278, 794, -1510, -854, -870, 478,
-108, -308, 996, 991, 958, -1460, 1522, 1628
};
static int16_t montgomery_reduce(int32_t a)
{
int16_t t;
t = (int16_t)a*KY_QINV;
t = (a - (int32_t)t*KY_PRIME) >> 16;
return t;
}
static int16_t barrett_reduce(int16_t a) {
int16_t t;
const int16_t v = ((1<<26) + KY_PRIME/2)/KY_PRIME;
t = ((int32_t)v*a + (1<<25)) >> 26;
t *= KY_PRIME;
return a - t;
}
static sign16 fqmul(sign16 a, sign16 b) {
return montgomery_reduce((sign32)a*b);
}
static void ntt(int16_t r[256]) {
unsigned int len, start, j, k;
int16_t t, zeta;
k = 1;
for(len = 128; len >= 2; len >>= 1) {
for(start = 0; start < 256; start = j + len) {
zeta = zetas[k++];
for(j = start; j < start + len; j++) {
t = fqmul(zeta, r[j + len]);
r[j + len] = r[j] - t;
r[j] = r[j] + t;
}
}
}
}
static void invntt(int16_t r[256]) {
unsigned int start, len, j, k;
int16_t t, zeta;
const int16_t f = 1441; // mont^2/128
k = 127;
for(len = 2; len <= 128; len <<= 1) {
for(start = 0; start < 256; start = j + len) {
zeta = zetas[k--];
for(j = start; j < start + len; j++) {
t = r[j];
r[j] = barrett_reduce(t + r[j + len]);
r[j + len] = r[j + len] - t;
r[j + len] = fqmul(zeta, r[j + len]);
}
}
}
for(j = 0; j < 256; j++)
r[j] = fqmul(r[j], f);
}
static void basemul(sign16 r[2], const sign16 a[2], const sign16 b[2], sign16 zeta) {
r[0] = fqmul(a[1], b[1]);
r[0] = fqmul(r[0], zeta);
r[0] += fqmul(a[0], b[0]);
r[1] = fqmul(a[0], b[1]);
r[1] += fqmul(a[1], b[0]);
}
static void poly_reduce(sign16 *r)
{
int i;
for(i=0;i<KY_DEGREE;i++)
r[i] = barrett_reduce(r[i]);
}
static void poly_ntt(sign16 *r)
{
ntt(r);
poly_reduce(r);
}
static void poly_invntt(sign16 *r)
{
invntt(r);
}
// Note r must be distinct from a and b
static void poly_mul(sign16 *r, const sign16 *a, const sign16 *b)
{
int i;
for(i = 0; i < KY_DEGREE/4; i++) {
basemul(&r[4*i], &a[4*i], &b[4*i], zetas[64 + i]);
basemul(&r[4*i + 2], &a[4*i + 2], &b[4*i + 2], -zetas[64 + i]);
}
}
static void poly_tomont(sign16 *r)
{
int i;
const sign16 f = KY_ONE;
for(i=0;i<KY_DEGREE;i++)
r[i] = montgomery_reduce((sign32)r[i]*f);
}
/* End of public domain reference code use */
// copy polynomial
static void poly_copy(sign16 *p1, sign16 *p2)
{
int i;
for (i = 0; i < KY_DEGREE; i++)
p1[i] = p2[i];
}
// zero polynomial
static void poly_zero(sign16 *p1)
{
int i;
for (i = 0; i < KY_DEGREE; i++)
p1[i] = 0;
}
// add polynomials
static void poly_add(sign16 *p1, sign16 *p2, sign16 *p3)
{
int i;
for (i = 0; i < KY_DEGREE; i++)
p1[i] = (p2[i] + p3[i]);
}
// subtract polynomials
static void poly_sub(sign16 *p1, sign16 *p2, sign16 *p3)
{
int i;
for (i = 0; i < KY_DEGREE; i++)
p1[i] = (p2[i] - p3[i]);
}
// Generate A[i][j] from rho
static void ExpandAij(byte rho[32],sign16 Aij[],int i,int j)
{
int m;
sha3 sh;
SHA3_init(&sh, SHAKE128);
byte buff[640]; // should be plenty (?)
for (m=0;m<32;m++)
SHA3_process(&sh,rho[m]);
SHA3_process(&sh,j&0xff);
SHA3_process(&sh,i&0xff);
SHA3_shake(&sh,(char *)buff,640);
i=j=0;
while (j<KY_DEGREE)
{
int d1=buff[i]+256*(buff[i+1]&0x0F);
int d2=buff[i+1]/16+16*buff[i+2];
if (d1<KY_PRIME)
Aij[j++]=d1;
if (d2<KY_PRIME && j<KY_DEGREE)
Aij[j++]=d2;
i+=3;
}
}
// get n-th bit from byte array
static int getbit(byte b[],int n)
{
int wd=n/8;
int bt=n%8;
return (b[wd]>>bt)&1;
}
// centered binomial distribution
static void CBD(byte bts[],int eta,sign16 f[KY_DEGREE])
{
int a,b;
for (int i=0;i<KY_DEGREE;i++)
{
a=b=0;
for (int j=0;j<eta;j++)
{
a+=getbit(bts,2*i*eta+j);
b+=getbit(bts,2*i*eta+eta+j);
}
f[i]=a-b;
}
}
// extract ab bits into word from dense byte stream
static sign16 nextword(int ab,byte t[],int &ptr, int &bts)
{
sign16 r=t[ptr]>>bts;
sign16 mask=(1<<ab)-1;
sign16 w;
int i=0;
int gotbits=8-bts; // bits left in current byte
while (gotbits<ab)
{
i++;
w=(sign16)t[ptr+i];
r|=w<<gotbits;
gotbits+=8;
}
bts+=ab;
while (bts>=8)
{
bts-=8;
ptr++;
}
w=r&mask;
return w;
}
// array t has ab active bits per word
// extract bytes from array of words
// if max!=0 then -max<=t[i]<=+max
static byte nextbyte16(int ab,sign16 t[],int &ptr, int &bts)
{
sign16 r,w;
int left=ab-bts; // number of bits left in this word
int i=0;
w=t[ptr]; w+=(w>>15)&KY_PRIME;
r=w>>bts;
while (left<8)
{
i++;
w=t[ptr+i]; w+=(w>>15)&KY_PRIME;
r|=w<<left;
left+=ab;
}
bts+=8;
while (bts>=ab)
{
bts-=ab;
ptr++;
}
return (byte)r&0xff;
}
// encode polynomial vector of length len with coefficients of length L, into packed bytes
static void encode(sign16 t[],int len,int L,byte pack[])
{
int ptr,bts,n;
ptr=bts=0;
for (n=0;n<len*(KY_DEGREE*L)/8;n++ ) {
pack[n]=nextbyte16(L,t,ptr,bts);
}
}
static byte chk_encode(sign16 t[],int len,int L,byte pack[])
{
int ptr,bts,n;
byte m,diff=0;
ptr=bts=0;
for (n=0;n<len*(KY_DEGREE*L)/8;n++ ) {
m=nextbyte16(L,t,ptr,bts);
diff|=(m^pack[n]);
}
return diff;
}
// decode packed bytes into polynomial vector of length len, with coefficients of length L
static void decode(byte pack[],int L,sign16 t[],int len)
{
int ptr,bts,i;
ptr=bts=0;
for (i=0;i<len*KY_DEGREE;i++ )
t[i]=nextword(L,pack,ptr,bts);
}
// Bernsteins safe division by 0xD01
static int32_t safediv(int32_t x)
{
int32_t qpart,q=0;
qpart=(int32_t)(((int64_t)x*645083)>>31);
x-=qpart*0xD01; q += qpart;
qpart=(int32_t)(((int64_t)x*645083)>>31)+1;
x-=qpart*0xD01; q += qpart+(x>>31);
return q;
}
// compress polynomial coefficents in place, for polynomial vector of length len
static void compress(sign16 t[],int len,int d)
{
sign32 twod=(1<<d);
for (int i=0;i<len*KY_DEGREE;i++)
{
t[i]+=(t[i]>>15)&KY_PRIME;
t[i]= (sign16)(safediv(twod*t[i]+KY_PRIME/2)&(twod-1));
}
}
// decompress polynomial coefficents in place, for polynomial vector of length len
static void decompress(sign16 t[],int len,int d)
{
int twod1=(1<<(d-1));
for (int i=0;i<len*KY_DEGREE;i++)
t[i]=(KY_PRIME*t[i]+twod1)>>d;
}
// input entropy, output key pair
static void KYBER_CPA_keypair(const int *params,byte *tau,octet *sk,octet *pk)
{
int i,j,k,row;
sha3 sh;
byte rho[32];
byte sigma[33];
byte buff[256];
int ck=params[0];
sign16 r[KY_DEGREE];
sign16 w[KY_DEGREE];
sign16 Aij[KY_DEGREE];
#ifdef USE_VLAS
sign16 s[ck*KY_DEGREE];
sign16 e[ck*KY_DEGREE];
sign16 p[ck*KY_DEGREE];
#else
sign16 s[KY_MAXK*KY_DEGREE];
sign16 e[KY_MAXK*KY_DEGREE];
sign16 p[KY_MAXK*KY_DEGREE];
#endif
int eta1=params[1];
int public_key_size=32+ck*(KY_DEGREE*3)/2;
int secret_cpa_key_size=ck*(KY_DEGREE*3)/2;
SHA3_init(&sh,SHA3_HASH512);
for (i=0;i<32;i++)
SHA3_process(&sh,tau[i]);
SHA3_hash(&sh,(char *)buff);
for (i=0;i<32;i++)
{
rho[i]=buff[i];
sigma[i]=buff[i+32];
}
sigma[32]=0; // N
// create s
for (i=0;i<ck;i++)
{
SHA3_init(&sh,SHAKE256);
for (j=0;j<33;j++)
SHA3_process(&sh,sigma[j]);
SHA3_shake(&sh,(char *)buff,64*eta1);
CBD(buff,eta1,&s[i*KY_DEGREE]);
sigma[32]+=1;
}
// create e
for (i=0;i<ck;i++)
{
SHA3_init(&sh,SHAKE256);
for (j=0;j<33;j++)
SHA3_process(&sh,sigma[j]);
SHA3_shake(&sh,(char *)buff,64*eta1);
CBD(buff,eta1,&e[i*KY_DEGREE]);
sigma[32]+=1;
}
for (k=0;k<ck;k++)
{
row=KY_DEGREE*k;
poly_ntt(&s[row]);
poly_ntt(&e[row]);
}
for (i=0;i<ck;i++)
{
row=KY_DEGREE*i;
ExpandAij(rho,Aij,i,0);
poly_mul(r,Aij,s);
for (j=1;j<ck;j++)
{
ExpandAij(rho,Aij,i,j);
poly_mul(w,&s[j*KY_DEGREE],Aij);
poly_add(r,r,w);
}
poly_reduce(r);
poly_tomont(r);
poly_add(&p[row],r,&e[row]);
poly_reduce(&p[row]);
}
encode(s,ck,12,(byte *)sk->val);
sk->len=secret_cpa_key_size;
encode(p,ck,12,(byte *)pk->val);
pk->len=public_key_size;
for (i=0;i<32;i++)
pk->val[public_key_size-32+i]=rho[i];
}
// input 64 random bytes, output secret and public keys
static void KYBER_CCA_keypair(const int *params,byte *randbytes64,octet *sk,octet *pk)
{
int i;
sha3 sh;
byte h[32];
KYBER_CPA_keypair(params,randbytes64,sk,pk);
OCT_joctet(sk,pk);
SHA3_init(&sh,SHA3_HASH256);
for (i=0;i<pk->len;i++)
SHA3_process(&sh,(byte)pk->val[i]);
SHA3_hash(&sh,(char *)h);
OCT_jbytes(sk,(char *)h,32);
OCT_jbytes(sk,(char *)&randbytes64[32],32);
}
static void KYBER_CPA_base_encrypt(const int *params,byte *coins,octet *pk,octet *ss,sign16 *u, sign16* v)
{
int i,row,j,len;
sha3 sh;
byte sigma[33];
byte buff[256];
byte rho[32];
int ck=params[0];
sign16 r[KY_DEGREE];
sign16 w[KY_DEGREE];
sign16 Aij[KY_DEGREE];
#ifdef USE_VLAS
sign16 q[ck*KY_DEGREE];
sign16 p[ck*KY_DEGREE];
#else
sign16 q[KY_MAXK*KY_DEGREE];
sign16 p[KY_MAXK*KY_DEGREE];
#endif
int eta1=params[1];
int eta2=params[2];
int du=params[3];
int dv=params[4];
int public_key_size=32+ck*(KY_DEGREE*3)/2;
for (i=0;i<32;i++)
sigma[i]=coins[i];//i+6; //RAND_byte(RNG);
sigma[32]=0;
for (i=0;i<32;i++)
rho[i]=pk->val[pk->len-32+i];
// create q
for (i=0;i<ck;i++)
{
SHA3_init(&sh,SHAKE256);
for (j=0;j<33;j++)
SHA3_process(&sh,sigma[j]);
SHA3_shake(&sh,(char *)buff,64*eta1);
CBD(buff,eta1,&q[i*KY_DEGREE]);
sigma[32]+=1;
}
// create e1
for (i=0;i<ck;i++)
{
SHA3_init(&sh,SHAKE256);
for (j=0;j<33;j++)
SHA3_process(&sh,sigma[j]);
SHA3_shake(&sh,(char *)buff,64*eta2);
CBD(buff,eta1,&u[i*KY_DEGREE]); // e1
sigma[32]+=1;
}
for (i=0;i<ck;i++)
{
row=KY_DEGREE*i;
poly_ntt(&q[row]);
}
for (i=0;i<ck;i++)
{
row=KY_DEGREE*i;
ExpandAij(rho,Aij,0,i);
poly_mul(r,Aij,q);
for (j=1;j<ck;j++)
{
ExpandAij(rho,Aij,j,i);
poly_mul(w,&q[j*KY_DEGREE],Aij);
poly_add(r,r,w);
}
poly_reduce(r);
poly_invntt(r);
poly_add(&u[row],&u[row],r);
poly_reduce(&u[row]);
}
decode((byte *)pk->val,12,p,ck);
poly_mul(v,p,q);
for (i=1;i<ck;i++)
{
row=KY_DEGREE*i;
poly_mul(r,&p[row],&q[row]);
poly_add(v,v,r);
}
poly_invntt(v);
// create e2
SHA3_init(&sh,SHAKE256);
for (j=0;j<33;j++)
SHA3_process(&sh,sigma[j]);
SHA3_shake(&sh,(char *)buff,64*eta2);
CBD(buff,eta1,w); // e2
poly_add(v,v,w);
decode((byte *)ss->val,1,r,1);
decompress(r,1,1);
poly_add(v,v,r);
poly_reduce(v);
compress(u,ck,du);
compress(v,1,dv);
}
// Given input of entropy, public key and shared secret is an input, outputs ciphertext
static void KYBER_CPA_encrypt(const int *params,byte *coins,octet *pk,octet *ss,octet *ct)
{
int ck=params[0];
sign16 v[KY_DEGREE];
#ifdef USE_VLAS
sign16 u[ck*KY_DEGREE];
#else
sign16 u[KY_MAXK*KY_DEGREE];
#endif
int du=params[3];
int dv=params[4];
int ciphertext_size=(du*ck+dv)*KY_DEGREE/8;
KYBER_CPA_base_encrypt(params,coins,pk,ss,u,v);
encode(u,ck,du,(byte *)ct->val);
encode(v,1,dv,(byte *)&ct->val[ciphertext_size-(dv*KY_DEGREE/8)]);
ct->len=ciphertext_size;
}
// Re-encrypt and check that ct is OK (if so return is zero)
static byte KYBER_CPA_check_encrypt(const int *params,byte *coins,octet *pk,octet *ss,octet *ct)
{
int ck=params[0];
sign16 v[KY_DEGREE];
#ifdef USE_VLAS
sign16 u[ck*KY_DEGREE];
#else
sign16 u[KY_MAXK*KY_DEGREE];
#endif
int du=params[3];
int dv=params[4];
int ciphertext_size=(du*ck+dv)*KY_DEGREE/8;
byte d1,d2;
KYBER_CPA_base_encrypt(params,coins,pk,ss,u,v);
d1=chk_encode(u,ck,du,(byte *)ct->val);
d2=chk_encode(v,1,dv,(byte *)&ct->val[ciphertext_size-(dv*KY_DEGREE/8)]);
if ((d1|d2)==0)
return 0;
else
return 0xff;
}
// Given entropy and public key, outputs 32-byte shared secret and ciphertext
static void KYBER_CCA_encrypt(const int *params,byte *randbytes32,octet *pk,octet *ss,octet *ct)
{
int i;
sha3 sh;
byte h[32],hm[32],g[64],coins[32];
octet HM={32,sizeof(hm),(char *)hm};
int ck=params[0];
int du=params[3];
int dv=params[4];
int shared_secret_size=params[5];
SHA3_init(&sh,SHA3_HASH256); // H(m)
for (i=0;i<32;i++)
SHA3_process(&sh,randbytes32[i]);
SHA3_hash(&sh,(char *)hm);
SHA3_init(&sh,SHA3_HASH256); // H(pk)
for (i=0;i<pk->len;i++)
SHA3_process(&sh,(byte)pk->val[i]);
SHA3_hash(&sh,(char *)h);
SHA3_init(&sh,SHA3_HASH512); // Kb,r = G(H(m)|H(pk)
for (i=0;i<32;i++)
SHA3_process(&sh,hm[i]);
for (i=0;i<32;i++)
SHA3_process(&sh,h[i]);
SHA3_hash(&sh,(char *)g);
for (i=0;i<32;i++)
coins[i]=g[i+32];
KYBER_CPA_encrypt(params,coins,pk,&HM,ct);
SHA3_init(&sh,SHA3_HASH256); // H(ct)
for (i=0;i<ct->len;i++)
SHA3_process(&sh,(byte)ct->val[i]);
SHA3_hash(&sh,(char *)h);
SHA3_init(&sh,SHAKE256); // K=KDF(Kb|H(ct))
for (i=0;i<32;i++)
SHA3_process(&sh,g[i]);
for (i=0;i<32;i++)
SHA3_process(&sh,h[i]);
SHA3_shake(&sh,ss->val,shared_secret_size); // could be any length?
ss->len=shared_secret_size;
}
// Input secret key and ciphertext, outputs shared 32-byte secret
static void KYBER_CPA_decrypt(const int *params,octet *sk,octet *ct,octet *ss)
{
int i,j,row;
int ck=params[0];
sign16 w[KY_DEGREE];
sign16 v[KY_DEGREE];
sign16 r[KY_DEGREE];
#ifdef USE_VLAS
sign16 u[ck*KY_DEGREE];
sign16 s[ck*KY_DEGREE];
#else
sign16 u[KY_MAXK*KY_DEGREE];
sign16 s[KY_MAXK*KY_DEGREE];
#endif
int du=params[3];
int dv=params[4];
int shared_secret_size=params[5];
decode((byte *)ct->val,du,u,ck);
decode((byte *)&ct->val[du*ck*KY_DEGREE/8],dv,v,1);
decompress(u,ck,du);
decompress(v,1,dv);
decode((byte *)sk->val,12,s,ck);
poly_ntt(u);
poly_mul(w,u,s);
for (i=1;i<ck;i++)
{
row=KY_DEGREE*i;
poly_ntt(&u[row]);
poly_mul(r,&u[row],&s[row]);
poly_add(w,w,r);
}
poly_reduce(w);
poly_invntt(w);
poly_sub(v,v,w);
compress(v,1,1);
encode(v,1,1,(byte *)ss->val);
ss->len=shared_secret_size;
}
static void KYBER_CCA_decrypt(const int *params,octet *sk,octet *ct,octet *ss)
{
int i,olen,same;
sha3 sh;
byte h[32],z[32],m[32],coins[32],g[64],mask;
octet M={32,sizeof(m),(char *)m};
int ck=params[0];
int du=params[3];
int dv=params[4];
int secret_cpa_key_size=ck*(KY_DEGREE*3)/2;
int public_key_size=32+ck*(KY_DEGREE*3)/2;
int shared_secret_size=params[5];
octet PK={public_key_size,public_key_size,&sk->val[secret_cpa_key_size]}; // public key is here
olen=sk->len;
sk->len=secret_cpa_key_size; // chop off CPA secret
for (i=0;i<32;i++)
h[i]=sk->val[secret_cpa_key_size+public_key_size+i];
for (i=0;i<32;i++)
z[i]=sk->val[secret_cpa_key_size+public_key_size+32+i];
KYBER_CPA_decrypt(params,sk,ct,&M);
SHA3_init(&sh,SHA3_HASH512); // Kb,r = G(H(m)|H(pk)
for (i=0;i<32;i++)
SHA3_process(&sh,m[i]);
for (i=0;i<32;i++)
SHA3_process(&sh,h[i]);
SHA3_hash(&sh,(char *)g);
for (i=0;i<32;i++)
coins[i]=g[i+32];
mask=KYBER_CPA_check_encrypt(params,coins,&PK,&M,ct); // encrypt again with public key - FO transform CPA->CCA
for (i=0;i<32;i++)
g[i]^=(g[i]^z[i])&mask; // substitute z for Kb on failure
SHA3_init(&sh,SHA3_HASH256); // H(ct)
for (i=0;i<ct->len;i++)
SHA3_process(&sh,(byte)ct->val[i]);
SHA3_hash(&sh,(char *)h);
SHA3_init(&sh,SHAKE256); // K=KDF(Kb|H(ct))
for (i=0;i<32;i++)
SHA3_process(&sh,g[i]);
for (i=0;i<32;i++)
SHA3_process(&sh,h[i]);
SHA3_shake(&sh,ss->val,shared_secret_size); // could be any length?
ss->len=shared_secret_size;
sk->len=olen; // restore length
}
// ********************* Kyber API ******************************
void core::KYBER512_keypair(byte *r64,octet *SK,octet *PK)
{
KYBER_CCA_keypair(PARAMS_512,r64,SK,PK);
}
void core::KYBER768_keypair(byte *r64,octet *SK,octet *PK)
{
KYBER_CCA_keypair(PARAMS_768,r64,SK,PK);
}
void core::KYBER1024_keypair(byte *r64,octet *SK,octet *PK)
{
KYBER_CCA_keypair(PARAMS_1024,r64,SK,PK);
}
void core::KYBER512_encrypt(byte *r32,octet *PK,octet *SS,octet *CT)
{
KYBER_CCA_encrypt(PARAMS_512,r32,PK,SS,CT);
}
void core::KYBER768_encrypt(byte *r32,octet *PK,octet *SS,octet *CT)
{
KYBER_CCA_encrypt(PARAMS_768,r32,PK,SS,CT);
}
void core::KYBER1024_encrypt(byte *r32,octet *PK,octet *SS,octet *CT)
{
KYBER_CCA_encrypt(PARAMS_1024,r32,PK,SS,CT);
}
void core::KYBER512_decrypt(octet *SK,octet *CT,octet *SS)
{
KYBER_CCA_decrypt(PARAMS_512,SK,CT,SS);
}
void core::KYBER768_decrypt(octet *SK,octet *CT,octet *SS)
{
KYBER_CCA_decrypt(PARAMS_768,SK,CT,SS);
}
void core::KYBER1024_decrypt(octet *SK,octet *CT,octet *SS)
{
KYBER_CCA_decrypt(PARAMS_1024,SK,CT,SS);
}