Crypt-PQClean-Sign
view release on metacpan or search on metacpan
pqclean/crypto_kem/hqc-128/clean/reed_muller.c view on Meta::CPAN
/**
* @brief Finding the location of the highest value
*
* This is the final step of the green machine: find the location of the highest value,
* and add 128 if the peak is positive
* if there are two identical peaks, the peak with smallest value
* in the lowest 7 bits it taken
* @param[in] transform Structure that contain the expanded codeword
*/
static uint8_t find_peaks(const uint16_t transform[128]) {
uint16_t peak_abs = 0;
uint16_t peak = 0;
uint16_t pos = 0;
uint16_t t, abs, mask;
for (uint16_t i = 0; i < 128; ++i) {
t = transform[i];
abs = t ^ ((uint16_t)(-(t >> 15)) & (t ^ -t)); // t = abs(t)
mask = -(((uint16_t)(peak_abs - abs)) >> 15);
peak ^= mask & (peak ^ t);
pos ^= mask & (pos ^ i);
peak_abs ^= mask & (peak_abs ^ abs);
}
// set bit 7
pos |= 128 & (uint16_t)((peak >> 15) - 1);
return (uint8_t) pos;
}
/**
* @brief Encodes the received word
*
* The message consists of N1 bytes each byte is encoded into PARAM_N2 bits,
* or MULTIPLICITY repeats of 128 bits
*
* @param[out] cdw Array of size VEC_N1N2_SIZE_64 receiving the encoded message
* @param[in] msg Array of size VEC_N1_SIZE_64 storing the message
*/
void PQCLEAN_HQC128_CLEAN_reed_muller_encode(uint64_t *cdw, const uint8_t *msg) {
for (size_t i = 0; i < VEC_N1_SIZE_BYTES; ++i) {
// encode first word
encode(&cdw[2 * i * MULTIPLICITY], msg[i]);
// copy to other identical codewords
for (size_t copy = 1; copy < MULTIPLICITY; ++copy) {
memcpy(&cdw[2 * i * MULTIPLICITY + 2 * copy], &cdw[2 * i * MULTIPLICITY], 16);
}
}
}
/**
* @brief Decodes the received word
*
* Decoding uses fast hadamard transform, for a more complete picture on Reed-Muller decoding, see MacWilliams, Florence Jessie, and Neil James Alexander Sloane.
* The theory of error-correcting codes codes @cite macwilliams1977theory
*
* @param[out] msg Array of size VEC_N1_SIZE_64 receiving the decoded message
* @param[in] cdw Array of size VEC_N1N2_SIZE_64 storing the received word
*/
void PQCLEAN_HQC128_CLEAN_reed_muller_decode(uint8_t *msg, const uint64_t *cdw) {
uint16_t expanded[128];
uint16_t transform[128];
for (size_t i = 0; i < VEC_N1_SIZE_BYTES; ++i) {
// collect the codewords
expand_and_sum(expanded, &cdw[2 * i * MULTIPLICITY]);
// apply hadamard transform
hadamard(expanded, transform);
// fix the first entry to get the half Hadamard transform
transform[0] -= 64 * MULTIPLICITY;
// finish the decoding
msg[i] = find_peaks(transform);
}
}
( run in 0.414 second using v1.01-cache-2.11-cpan-bbb979687b5 )