packages feed

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);
}