ml: Properly implement ByteDecode with d=12
I've overlooked the "m = q if d = 12" note in the pseudo-code for
Algorithm 6. The text further up in the section actually clarifies
this:
For d = 12, ByteDecode produces integers modulo q as output...(it)
converts each 12-bit segment of its input into an integer modulo 4096
and then reduces the result modulo q. This is no longer a one-to-one
operation.
This did not have any practical impact (other than accepting public keys
that are technically non-compliant) because the values would get properly
reduced anyway by the Barrett reduction used in `mul_modq()`.
Fixes: 89f4b345e3 ("ml: Add software implementation of ML-KEM")
This commit is contained in:
@@ -402,18 +402,24 @@ static void encode_poly_arr(uint8_t k, ml_poly_t *a, uint8_t *out)
|
||||
* Decode k polynomials from a byte array (12-bit version that unpacks 2
|
||||
* coefficients from 3 bytes, not using ml_bitpacker_t for performance reasons).
|
||||
*
|
||||
* As described in section 4.2.1, d=12 is a special version of ByteDecode that
|
||||
* does a reduction mod q.
|
||||
*
|
||||
* Algorithm 6 in FIPS 203.
|
||||
*/
|
||||
static void decode_poly_arr(uint8_t k, uint8_t *in, ml_poly_t *a)
|
||||
{
|
||||
uint16_t f0, f1;
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < k; i++)
|
||||
{
|
||||
for (j = 0; j < ML_KEM_N / 2; j++)
|
||||
{
|
||||
a[i].f[2*j] = (in[3*j] | ((uint16_t)in[3*j+1] << 8)) & 0xfff;
|
||||
a[i].f[2*j+1] = ((in[3*j+1] >> 4) | ((uint16_t)in[3*j+2] << 4)) & 0xfff;
|
||||
f0 = ( in[3*j] | ((uint16_t)in[3*j+1] << 8)) & 0xfff;
|
||||
f1 = ((in[3*j+1] >> 4) | ((uint16_t)in[3*j+2] << 4)) & 0xfff;
|
||||
a[i].f[2*j] = ml_reduce_modq(f0);
|
||||
a[i].f[2*j+1] = ml_reduce_modq(f1);
|
||||
}
|
||||
in += ML_KEM_POLY_LEN;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user