packages feed

KpqC-0.1.0: cbits/third_party/SMAUG-T/src/pack.c

// SPDX-License-Identifier: MIT

#include "pack.h"
#include "packring.h"

#include <string.h>

/*************************************************
 * Name:        pack_enck
 *
 * Description: pack an encryption key to a byte array
 *
 * Arguments:   - uint8_t *output: pointer to output byte array
 *              - const public_key *pk: pointer to input public key
 *
 * Specification: Implements @[KS X 123456, Algorithm 14, PackEncK]
 **************************************************/
void pack_enck(uint8_t *output, const public_key *pk) {
    memcpy(output, pk->seed, sizeof(uint8_t) * SMAUGT_PKSEED_BYTES);
    pack_ring_vec(output + SMAUGT_PKSEED_BYTES, &(pk->b));
}

/*************************************************
 * Name:        unpack_enck
 *
 * Description: unpack a byte array to an encryption key
 *
 * Arguments:   - public_key *pk: pointer to output public key
 *              - const uint8_t *input: pointer to input byte array
 *
 * Specification: Implements @[KS X 123456, Algorithm 15, UnpackEncK]
 **************************************************/
void unpack_enck(public_key *pk, const uint8_t *input) {
    memcpy(pk->seed, input, SMAUGT_PKSEED_BYTES);
    expand_A(pk->A, pk->seed);
    unpack_ring_vec(&(pk->b), input + SMAUGT_PKSEED_BYTES);
}

/*************************************************
 * Name:        pack_deck
 *
 * Description: pack a decryption key to a byte array
 *
 * Arguments:   - uint8_t *output: pointer to output byte array
 *              - const secret_key *sk: pointer to input private key
 *
 * Specification: Implements @[KS X 123456, Algorithm 16, PackDecK]
 **************************************************/
void pack_deck(uint8_t *output, const secret_key *sk) {
    for (size_t i = 0; i < SMAUGT_K; ++i)
        pack_s_poly(output + SMAUGT_SKPOLY_BYTES * i, &sk->vec[i]);
}

/*************************************************
 * Name:        unpack_deck
 *
 * Description: unpack a byte array to a decryption key
 *
 * Arguments:   - secret_key *sk: pointer to output private key
 *              - const uint8_t *input: pointer to input byte array
 *
 * Specification: Implements @[KS X 123456, Algorithm 17, UnpackDecK]
 **************************************************/
void unpack_deck(secret_key *sk, const uint8_t *input) {
    for (size_t i = 0; i < SMAUGT_K; ++i)
        unpack_s_poly(&sk->vec[i], input + SMAUGT_SKPOLY_BYTES * i);
}

/*************************************************
 * Name:        pack_s_poly
 *
 * Description: Transform to bytes array from a degree of array of secrey poly
 *
 * Arguments:   - uint8_t *bytes: pointer to output bytes
 *              - const poly *s: pointer to input poly in Sn
 *
 * Specification: Implements @[KS X 123456, Algorithm 18, PackSPoly]
 **************************************************/
void pack_s_poly(uint8_t *bytes, const poly *s) {
    unsigned int i;
    int d_idx = 0;
    for (i = 0; i < SMAUGT_N / 4; ++i) {
        d_idx = i * 4;
        bytes[i] = ((1 - s->coeffs[d_idx]) & 0x03) |
                   (((1 - s->coeffs[d_idx + 1]) & 0x03) << 2) |
                   (((1 - s->coeffs[d_idx + 2]) & 0x03) << 4) |
                   (((1 - s->coeffs[d_idx + 3]) & 0x03) << 6);
    }
}

/*************************************************
 * Name:        unpack_s_poly
 *
 * Description: Transform to a degree of array of secrey poly from bytes array
 *
 * Arguments:   - poly *s: pointer to output poly in Sn
 *              - const uint8_t *bytes: pointer to input bytes
 *
 * Specification: Implements @[KS X 123456, Algorithm 19, UnpackSPoly]
 **************************************************/
void unpack_s_poly(poly *s, const uint8_t *bytes) {
    unsigned int i;
    int d_idx = 0;
    for (i = 0; i < SMAUGT_N / 4; ++i) {
        d_idx = i * 4;
        uint8_t t[4] = {0};
        t[0] = (bytes[i] & 0x03);
        t[1] = ((bytes[i] >> 2) & 0x03);
        t[2] = ((bytes[i] >> 4) & 0x03);
        t[3] = ((bytes[i] >> 6) & 0x03);
        s->coeffs[d_idx] = 1 - t[0];
        s->coeffs[d_idx + 1] = 1 - t[1];
        s->coeffs[d_idx + 2] = 1 - t[2];
        s->coeffs[d_idx + 3] = 1 - t[3];
    }
}

/*************************************************
 * Name:        pack_ct
 *
 * Description: pack a ciphertext to a byte array
 *
 * Arguments:   - uint8_t *output: pointer to output byte array
 *              - const ciphertext *ctxt: pointer to input ciphertext
 *
 * Specification: Implements @[KS X 123456, Algorithm 20, PackCT]
 * **************************************************/
void pack_ct(uint8_t *output, const ciphertext *ctxt) {
    pack_ring_p_vec(output, &(ctxt->c1));
    pack_ring_p_prime(output + SMAUGT_CTPOLYVEC_BYTES, &(ctxt->c2));
}

/*************************************************
 * Name:        unpack_ct
 *
 * Description: unpack a byte array to a ciphertext
 *
 * Arguments:   - ciphertext *ctxt: pointer to output ciphertext
 *              - const uint8_t *input: pointer to input byte array
 *
 * Specification: Implements @[KS X 123456, Algorithm 21, UnpackCT]
 **************************************************/
void unpack_ct(ciphertext *ctxt, const uint8_t *input) {
    unpack_ring_p_vec(&(ctxt->c1), input);
    unpack_ring_p_prime(&(ctxt->c2), input + SMAUGT_CTPOLYVEC_BYTES);
}

/*************************************************
 * Name:        pack_ring
 *
 * Description: Transform to bytes array from polynomial in Rq
 *
 * Arguments:   - uint8_t bytes[SMAUGT_PKPOLY_BYTES]: pointer to output bytes
 *              - const poly *data: pointer to input polynomial in Rq
 **************************************************/
void pack_ring(uint8_t bytes[SMAUGT_PKPOLY_BYTES], const poly *data) {
#if SMAUGT_LOG_Q == 10
    pack_R2_10(bytes, data);
#elif SMAUGT_LOG_Q == 11
    pack_R2_11(bytes, data);
#endif
}

/*************************************************
 * Name:        unpack_ring
 *
 * Description: Transform to polynomial in Rq from bytes array
 *
 * Arguments:   - poly *data: pointer to output polynomial in Rq
 *              - const uint8_t bytes[SMAUGT_PKPOLY_BYTES]: pointer to input
 * bytes
 **************************************************/
void unpack_ring(poly *data, const uint8_t bytes[SMAUGT_PKPOLY_BYTES]) {
#if SMAUGT_LOG_Q == 10
    unpack_R2_10(data, bytes);
#elif SMAUGT_LOG_Q == 11
    unpack_R2_11(data, bytes);
#endif
}

/*************************************************
 * Name:        pack_ring_p
 *
 * Description: Transform to bytes array from polynomial in Rp
 *
 * Arguments:   - uint8_t bytes[SMAUGT_CTPOLY1_BYTES]: pointer to output bytes
 *              - const poly *data: pointer to input polynomial in Rp
 **************************************************/
void pack_ring_p(uint8_t bytes[SMAUGT_CTPOLY1_BYTES], const poly *data) {
#if SMAUGT_LOG_P == 8
    pack_R2_8(bytes, data);
#elif SMAUGT_LOG_P == 9
    pack_R2_9(bytes, data);
#endif
}

/*************************************************
 * Name:        unpack_ring_p
 *
 * Description: Transform to polynomial in Rp from bytes array
 *
 * Arguments:   - poly *data: pointer to output polynomial in Rp
 *              - const uint8_t bytes[SMAUGT_CTPOLY1_BYTES]: pointer to input
 * bytes
 **************************************************/
void unpack_ring_p(poly *data, const uint8_t bytes[SMAUGT_CTPOLY1_BYTES]) {
#if SMAUGT_LOG_P == 8
    unpack_R2_8(data, bytes);
#elif SMAUGT_LOG_P == 9
    unpack_R2_9(data, bytes);
#endif
}

/*************************************************
 * Name:        pack_ring_p_prime
 *
 * Description: Transform to bytes array from polynomial in Rp'
 *
 * Arguments:   - uint8_t bytes[SMAUGT_CTPOLY2_BYTES]: pointer to output bytes
 *              - const poly *data: pointer to input polynomial in Rp'
 **************************************************/
void pack_ring_p_prime(uint8_t bytes[SMAUGT_CTPOLY2_BYTES], const poly *data) {
#if SMAUGT_LOG_P_PRIME == 3
    pack_R2_3(bytes, data);
#elif SMAUGT_LOG_P_PRIME == 4
    pack_R2_4(bytes, data);
#elif SMAUGT_LOG_P_PRIME == 5
    pack_R2_5(bytes, data);
#elif SMAUGT_LOG_P_PRIME == 7
    pack_R2_7(bytes, data);
#endif
}

/*************************************************
 * Name:        unpack_ring_p_prime
 *
 * Description: Transform to polynomial in Rp' from bytes array
 *
 * Arguments:   - poly *data: pointer to output polynomial in Rp'
 *              - const uint8_t bytes[SMAUGT_CTPOLY2_BYTES]: pointer to input
 * bytes
 **************************************************/
void unpack_ring_p_prime(poly *data,
                         const uint8_t bytes[SMAUGT_CTPOLY2_BYTES]) {
#if SMAUGT_LOG_P_PRIME == 3
    unpack_R2_3(data, bytes);
#elif SMAUGT_LOG_P_PRIME == 4
    unpack_R2_4(data, bytes);
#elif SMAUGT_LOG_P_PRIME == 5
    unpack_R2_5(data, bytes);
#elif SMAUGT_LOG_P_PRIME == 7
    unpack_R2_7(data, bytes);
#endif
}

/*************************************************
 * Name:        pack_ring_vec
 *
 * Description: Transform to bytes array from vector of polynomial in Rq
 *
 * Arguments:   - uint8_t bytes[SMAUGT_PKPOLYVEC_BYTES]: pointer to output bytes
 *              - const polyvec *data: pointer to input vector of polynomial in
 *              Rq
 **************************************************/
void pack_ring_vec(uint8_t bytes[SMAUGT_PKPOLYVEC_BYTES], const polyvec *data) {
    unsigned int i;
    for (i = 0; i < SMAUGT_K; ++i)
        pack_ring(bytes + i * SMAUGT_PKPOLY_BYTES, &(data->vec[i]));
}

/*************************************************
 * Name:        unpack_ring_vec
 *
 * Description: Transform to vector of polynomial in Rq from bytes array
 *
 * Arguments:   - polyvec *data: pointer to output a vector of poly in Rq
 *              - uint8_t *bytes: pointer to input bytes
 **************************************************/
void unpack_ring_vec(polyvec *data,
                     const uint8_t bytes[SMAUGT_PKPOLYVEC_BYTES]) {
    unsigned int i;
    for (i = 0; i < SMAUGT_K; ++i)
        unpack_ring(&(data->vec[i]), bytes + i * SMAUGT_PKPOLY_BYTES);
}

/*************************************************
 * Name:        pack_ring_p_vec
 *
 * Description: Transform to bytes array from vector of polynomial in Rp
 *
 * Arguments:   - uint8_t bytes[SMAUGT_CTPOLYVEC_BYTES]: pointer to output bytes
 *              - const polyvec *data: pointer to input vector of polynomial in
 *              Rp
 **************************************************/
void pack_ring_p_vec(uint8_t bytes[SMAUGT_CTPOLYVEC_BYTES],
                     const polyvec *data) {
    unsigned int i;
    for (i = 0; i < SMAUGT_K; ++i)
        pack_ring_p(bytes + i * SMAUGT_CTPOLY1_BYTES, &(data->vec[i]));
}

/*************************************************
 * Name:        unpack_ring_p_vec
 *
 * Description: Transform to vector of polynomial in Rp from bytes array
 *
 * Arguments:   - polyvec *data: pointer to output a vector of poly in Rp
 *              - const uint8_t bytes[SMAUGT_CTPOLYVEC_BYTES]: pointer to input
 *              bytes
 **************************************************/
void unpack_ring_p_vec(polyvec *data,
                       const uint8_t bytes[SMAUGT_CTPOLYVEC_BYTES]) {
    unsigned int i;
    for (i = 0; i < SMAUGT_K; ++i)
        unpack_ring_p(&(data->vec[i]), bytes + i * SMAUGT_CTPOLY1_BYTES);
}

/*************************************************
 * Name:        pack_ring_mat
 *
 * Description: Transform to bytes array from matrix of polynomial in Rq
 *
 * Arguments:   - uint8_t bytes[SMAUGT_PKPOLYMAT_BYTES]: pointer to output bytes
 *              - const polyvec data[SMAUGT_K]: pointer to input matrix of
 *              polynomial in Rq
 **************************************************/
void pack_ring_mat(uint8_t bytes[SMAUGT_PKPOLYMAT_BYTES],
                   const polyvec data[SMAUGT_K]) {
    unsigned int i;
    for (i = 0; i < SMAUGT_K; ++i)
        pack_ring_vec(bytes + i * SMAUGT_PKPOLYVEC_BYTES, &(data[i]));
}

/*************************************************
 * Name:        unpack_ring_mat
 *
 * Description: Transform to matrix of  polynomial in Rq from bytes array
 *
 * Arguments:   - polyvec data[SMAUGT_K]: pointer to output matrix of polynomial
 *              in Rq
 *              - const uint8_t bytes[SMAUGT_PKPOLYMAT_BYTES]: pointer to input
 *              bytes
 **************************************************/
void unpack_ring_mat(polyvec data[SMAUGT_K],
                     const uint8_t bytes[SMAUGT_PKPOLYMAT_BYTES]) {
    unsigned int i;
    for (i = 0; i < SMAUGT_K; ++i)
        unpack_ring_vec(&(data[i]), bytes + i * SMAUGT_PKPOLYVEC_BYTES);
}