KpqC-0.1.0: cbits/third_party/SMAUG-T/src/key.c
// SPDX-License-Identifier: MIT
#include "key.h"
#include "dg.h"
#include "fips202.h"
#include "hwt.h"
#include "pack.h"
#include "poly.h"
#include <string.h>
/*************************************************
* Name: expand_A
*
* Description: Deterministically generate public matrix A from a seed.
* Entries of the A are polynomials that look uniformly random.
*
* Arguments: - polyvec A[SMAUGT_K]: pointer to output matrix A
* - const uint8_t seed[SMAUGT_PKSEED_BYTES]: pointer to input seed
*
* Specification: Implements @[KS X 123456, Algorithm 1, ExpandA]
**************************************************/
void expand_A(polyvec A[SMAUGT_K], const uint8_t seed[SMAUGT_PKSEED_BYTES]) {
unsigned int i, j;
uint8_t buf[SMAUGT_PKPOLY_BYTES] = {0}, extseed[SMAUGT_PKSEED_BYTES + 2];
memcpy(extseed, seed, SMAUGT_PKSEED_BYTES);
for (i = 0; i < SMAUGT_K; i++) {
for (j = 0; j < SMAUGT_K; j++) {
extseed[32] = i;
extseed[33] = j;
shake128(buf, SMAUGT_PKPOLY_BYTES, extseed,
SMAUGT_PKSEED_BYTES + 2);
unpack_ring(&A[i].vec[j], buf);
}
}
}
/*************************************************
* Name: expand_b
*
* Description: Generate public vector b from a matrix A, vector s and noise e.
* Random noise e is generated by Gaussian sampling.
*
* Arguments: - polyvec *b: pointer to output vector b
* - const polyvec A[SMAUGT_K]: pointer to input matrix A
* - const polyvec *s: pointer to input vector s
* - const uint8_t e_seed[SMAUGT_CRYPTO_BYTES]: pointer to input
* seed of error
**************************************************/
void expand_b(polyvec *b, const polyvec A[SMAUGT_K], const polyvec *s,
const uint8_t e_seed[SMAUGT_CRYPTO_BYTES]) {
// b = e
d_gaussian(b, e_seed);
// b = -a * s + e
matrix_vec_mult_sub(b, A, s);
}
/*************************************************
* Name: expand_s
*
* Description: Generate a vector of secret sparse polynomial s(x) from a seed.
*
* Arguments: - secret_key *sk: pointer to output private key
* - const uint8_t seed[SMAUGT_CRYPTO_BYTES]: pointer to input seed
* of s(x)
*
* Specification: Implements @[KS X 123456, Algorithm 2, ExpandS]
**************************************************/
void expand_s(secret_key *sk, const uint8_t seed[SMAUGT_CRYPTO_BYTES]) {
unsigned int i, j;
uint8_t extseed[SMAUGT_CRYPTO_BYTES + 2] = {0};
memcpy(extseed, seed, SMAUGT_CRYPTO_BYTES);
for (i = 0; i < SMAUGT_K; ++i) {
extseed[SMAUGT_CRYPTO_BYTES] = i * SMAUGT_K;
j = 0;
do {
extseed[SMAUGT_CRYPTO_BYTES + 1] = j;
j += 1;
} while (hwt(sk->vec[i].coeffs, extseed));
}
}
/*************************************************
* Name: genPubkey
*
* Description: Generate public key correspending to private key.
*
* Arguments: - public_key *pk: pointer to output public key
* - const secret_key *sk: pointer to input private key
* - const uint8_t err_seed[SMAUGT_CRYPTO_BYTES]: pointer to input
* seed of error
**************************************************/
void gen_pub_key(public_key *pk, const secret_key *sk,
const uint8_t err_seed[SMAUGT_CRYPTO_BYTES]) {
expand_A(pk->A, pk->seed);
memset(&(pk->b), 0, sizeof(uint16_t) * SMAUGT_N * SMAUGT_K);
// Initialized at addGaussian, Unnecessary
expand_b(&(pk->b), pk->A, sk, err_seed);
}