1
1
mirror of https://github.com/henrydcase/pqc.git synced 2024-12-04 21:34:01 +00:00
pqcrypto/crypto_kem/kyber768-90s/clean/aes256ctr.c

101 lines
3.5 KiB
C
Raw Normal View History

2019-09-17 13:02:01 +01:00
#include "aes256ctr.h"
#include "aes.h"
2019-09-17 13:02:01 +01:00
#include <stddef.h>
#include <stdint.h>
#include <string.h>
2019-10-04 12:10:29 +01:00
static inline void br_enc32be(unsigned char *dst, uint32_t x) {
dst[3] = (unsigned char)x;
dst[2] = (unsigned char)(x >> 8);
dst[1] = (unsigned char)(x >> 16);
dst[0] = (unsigned char)(x >> 24);
2019-09-17 13:02:01 +01:00
}
static void aes256_ctr_xof(unsigned char *out, size_t outlen, const unsigned char *iv, uint32_t ctr, const aes256ctx *ctx) {
2019-10-04 12:10:29 +01:00
uint8_t ivw[16];
uint8_t buf[AES_BLOCKBYTES];
2019-09-17 13:02:01 +01:00
size_t i;
memcpy(ivw, iv, AESCTR_NONCEBYTES);
2019-10-04 12:10:29 +01:00
br_enc32be(ivw + AESCTR_NONCEBYTES, ctr);
2019-09-17 13:02:01 +01:00
while (outlen > AES_BLOCKBYTES) {
2019-10-04 12:10:29 +01:00
aes256_ecb(out, ivw, 1, ctx);
br_enc32be(ivw + AESCTR_NONCEBYTES, ++ctr);
out += AES_BLOCKBYTES;
outlen -= AES_BLOCKBYTES;
2019-09-17 13:02:01 +01:00
}
if (outlen > 0) {
2019-10-04 12:10:29 +01:00
aes256_ecb(buf, ivw, 1, ctx);
for (i = 0; i < outlen; i++) {
out[i] = buf[i];
2019-09-17 13:02:01 +01:00
}
}
}
/*************************************************
* Name: aes256_prf
*
* Description: AES256 stream generation in CTR mode using 32-bit counter,
* nonce is zero-padded to 12 bytes, counter starts at zero
*
* Arguments: - uint8_t *output: pointer to output
* - size_t outlen: length of requested output in bytes
* - const uint8_t *key: pointer to 32-byte key
* - uint8_t nonce: 1-byte nonce (will be zero-padded to 12 bytes)
**************************************************/
void PQCLEAN_KYBER76890S_CLEAN_aes256_prf(uint8_t *output, size_t outlen, const uint8_t *key, uint8_t nonce) {
uint8_t iv[12];
for (int i = 1; i < 12; i++) {
iv[i] = 0;
}
iv[0] = nonce;
aes256ctx ctx;
aes256_ctr_keyexp(&ctx, key);
aes256_ctr(output, outlen, iv, &ctx);
aes256_ctx_release(&ctx);
2019-09-17 13:02:01 +01:00
}
/*************************************************
* Name: aes256xof_absorb
*
* Description: AES256 CTR used as a replacement for a XOF; this function
* "absorbs" a 32-byte key and two additional bytes that are zero-padded
* to a 12-byte nonce
*
* Arguments: - aes256xof_ctx *s: pointer to state to "absorb" key and IV into
* - const uint8_t *key: pointer to 32-byte key
* - uint8_t x: first additional byte to "absorb"
* - uint8_t y: second additional byte to "absorb"
**************************************************/
void PQCLEAN_KYBER76890S_CLEAN_aes256xof_absorb(aes256xof_ctx *s, const uint8_t *key, uint8_t x, uint8_t y) {
2020-03-27 01:11:07 +00:00
aes256_ecb_keyexp(&s->sk_exp, key);
2019-09-17 13:02:01 +01:00
for (int i = 2; i < 12; i++) {
s->iv[i] = 0;
2019-09-17 13:02:01 +01:00
}
s->iv[0] = x;
s->iv[1] = y;
s->ctr = 0;
2019-09-17 13:02:01 +01:00
}
/*************************************************
* Name: aes256xof_squeezeblocks
*
* Description: AES256 CTR used as a replacement for a XOF; this function
* generates 4 blocks out AES256-CTR output
*
* Arguments: - uint8_t *out: pointer to output
* - size_t nblocks: number of reqested 64-byte output blocks
* - aes256xof_ctx *s: AES "state", i.e. expanded key and IV
**************************************************/
void PQCLEAN_KYBER76890S_CLEAN_aes256xof_squeezeblocks(uint8_t *out, size_t nblocks, aes256xof_ctx *s) {
aes256_ctr_xof(out, nblocks * 64, s->iv, s->ctr, &s->sk_exp);
s->ctr += (uint32_t) (4 * nblocks);
2019-09-17 13:02:01 +01:00
}
/** Free the AES ctx **/
void PQCLEAN_KYBER76890S_CLEAN_aes256xof_ctx_release(aes256xof_ctx *s) {
aes256_ctx_release(&s->sk_exp);
}