Skip to content

Commit 11d00ff

Browse files
committed
Removed more "/KYBER_Q" from the source code, if compiled to DIV, they might be turned into a plaintext-checking oracle (thanks to Prasanna Ravi and Matthias Kannwischer for reporting!)
1 parent bc8e640 commit 11d00ff

6 files changed

Lines changed: 46 additions & 106 deletions

File tree

‎avx2/poly.c‎

Lines changed: 1 addition & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -22,94 +22,7 @@
2222
* (of length KYBER_POLYCOMPRESSEDBYTES)
2323
* - const poly *a: pointer to input polynomial
2424
**************************************************/
25-
#if (KYBER_POLYCOMPRESSEDBYTES == 96)
26-
void poly_compress(uint8_t r[96], const poly * restrict a)
27-
{
28-
unsigned int i;
29-
__m256i f0, f1, f2, f3;
30-
__m128i t0, t1;
31-
const __m256i v = _mm256_load_si256(&qdata.vec[_16XV/16]);
32-
const __m256i shift1 = _mm256_set1_epi16(1 << 8);
33-
const __m256i mask = _mm256_set1_epi16(7);
34-
const __m256i shift2 = _mm256_set1_epi16((8 << 8) + 1);
35-
const __m256i shift3 = _mm256_set1_epi32((64 << 16) + 1);
36-
const __m256i sllvdidx = _mm256_set1_epi64x(12LL << 32);
37-
const __m256i shufbidx = _mm256_set_epi8( 8, 2, 1, 0,-1,-1,-1,-1,14,13,12, 6, 5, 4,10, 9,
38-
-1,-1,-1,-1,14,13,12, 6, 5, 4,10, 9, 8, 2, 1, 0);
39-
40-
for(i=0;i<KYBER_N/64;i++) {
41-
f0 = _mm256_load_si256(&a->vec[4*i+0]);
42-
f1 = _mm256_load_si256(&a->vec[4*i+1]);
43-
f2 = _mm256_load_si256(&a->vec[4*i+2]);
44-
f3 = _mm256_load_si256(&a->vec[4*i+3]);
45-
f0 = _mm256_mulhi_epi16(f0,v);
46-
f1 = _mm256_mulhi_epi16(f1,v);
47-
f2 = _mm256_mulhi_epi16(f2,v);
48-
f3 = _mm256_mulhi_epi16(f3,v);
49-
f0 = _mm256_mulhrs_epi16(f0,shift1);
50-
f1 = _mm256_mulhrs_epi16(f1,shift1);
51-
f2 = _mm256_mulhrs_epi16(f2,shift1);
52-
f3 = _mm256_mulhrs_epi16(f3,shift1);
53-
f0 = _mm256_and_si256(f0,mask);
54-
f1 = _mm256_and_si256(f1,mask);
55-
f2 = _mm256_and_si256(f2,mask);
56-
f3 = _mm256_and_si256(f3,mask);
57-
f0 = _mm256_packus_epi16(f0,f1);
58-
f2 = _mm256_packus_epi16(f2,f3);
59-
f0 = _mm256_maddubs_epi16(f0,shift2); // a0 a1 a2 a3 b0 b1 b2 b3 a4 a5 a6 a7 b4 b5 b6 b7
60-
f2 = _mm256_maddubs_epi16(f2,shift2); // c0 c1 c2 c3 d0 d1 d2 d3 c4 c5 c6 c7 d4 d5 d6 d7
61-
f0 = _mm256_madd_epi16(f0,shift3); // a0 a1 b0 b1 a2 a3 b2 b3
62-
f2 = _mm256_madd_epi16(f2,shift3); // c0 c1 d0 d1 c2 c3 d2 d3
63-
f0 = _mm256_sllv_epi32(f0,sllvdidx);
64-
f2 = _mm256_sllv_epi32(f2,sllvdidx);
65-
f0 = _mm256_hadd_epi32(f0,f2); // a0 c0 c0 d0 a1 b1 c1 d1
66-
f0 = _mm256_permute4x64_epi64(f0,0xD8); // a0 b0 a1 b1 c0 d0 c1 d1
67-
f0 = _mm256_shuffle_epi8(f0,shufbidx);
68-
t0 = _mm256_castsi256_si128(f0);
69-
t1 = _mm256_extracti128_si256(f0,1);
70-
t0 = _mm_blend_epi32(t0,t1,0x08);
71-
_mm_storeu_si128((__m128i *)&r[24*i+ 0],t0);
72-
_mm_storel_epi64((__m128i *)&r[24*i+16],t1);
73-
}
74-
}
75-
76-
/*************************************************
77-
* Name: poly_decompress
78-
*
79-
* Description: De-serialization and subsequent decompression of a polynomial;
80-
* approximate inverse of poly_compress
81-
*
82-
* Arguments: - poly *r: pointer to output polynomial
83-
* - const uint8_t *a: pointer to input byte array
84-
* (of length KYBER_POLYCOMPRESSEDBYTES bytes)
85-
**************************************************/
86-
void poly_decompress(poly * restrict r, const uint8_t a[96])
87-
{
88-
unsigned int i;
89-
__m128i t;
90-
__m256i f;
91-
const __m256i q = _mm256_load_si256(&qdata.vec[_16XQ/16]);
92-
const __m256i shufbidx = _mm256_set_epi8(5,5,5,5,5,4,4,4,4,4,4,3,3,3,3,3,
93-
2,2,2,2,2,1,1,1,1,1,1,0,0,0,0,0);
94-
const __m256i mask = _mm256_set_epi16(224,28,896,112,14,448,56,7,
95-
224,28,896,112,14,448,56,7);
96-
const __m256i shift = _mm256_set_epi16(128,1024,32,256,2048,64,512,4096,
97-
128,1024,32,256,2048,64,512,4096);
98-
99-
for(i=0;i<KYBER_N/16;i++) {
100-
t = _mm_castps_si128(_mm_load_ss((float *)&a[6*i+0])));
101-
t = _mm_insert_epi16(t,*(int16_t *)&a[6*i+4],2);
102-
f = _mm256_broadcastsi128_si256(t);
103-
f = _mm256_blend_epi16(f,g,0x);
104-
f = _mm256_shuffle_epi8(f,shufbidx);
105-
f = _mm256_and_si256(f,mask);
106-
f = _mm256_mullo_epi16(f,shift);
107-
f = _mm256_mulhrs_epi16(f,q);
108-
_mm256_store_si256(&r->vec[i],f);
109-
}
110-
}
111-
112-
#elif (KYBER_POLYCOMPRESSEDBYTES == 128)
25+
#if (KYBER_POLYCOMPRESSEDBYTES == 128)
11326
void poly_compress(uint8_t r[128], const poly * restrict a)
11427
{
11528
unsigned int i;

‎ref/poly.c‎

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,23 @@
1818
void poly_compress(uint8_t r[KYBER_POLYCOMPRESSEDBYTES], const poly *a)
1919
{
2020
unsigned int i,j;
21-
int16_t u;
21+
int32_t u;
22+
uint32_t d0;
2223
uint8_t t[8];
2324

2425
#if (KYBER_POLYCOMPRESSEDBYTES == 128)
26+
2527
for(i=0;i<KYBER_N/8;i++) {
2628
for(j=0;j<8;j++) {
2729
// map to positive standard representatives
2830
u = a->coeffs[8*i+j];
2931
u += (u >> 15) & KYBER_Q;
30-
t[j] = ((((uint16_t)u << 4) + KYBER_Q/2)/KYBER_Q) & 15;
32+
/* t[j] = ((((uint16_t)u << 4) + KYBER_Q/2)/KYBER_Q) & 15; */
33+
d0 = u << 4;
34+
d0 += 1665;
35+
d0 *= 80635;
36+
d0 >>= 28;
37+
t[j] = d0 & 0xf;
3138
}
3239

3340
r[0] = t[0] | (t[1] << 4);
@@ -42,7 +49,12 @@ void poly_compress(uint8_t r[KYBER_POLYCOMPRESSEDBYTES], const poly *a)
4249
// map to positive standard representatives
4350
u = a->coeffs[8*i+j];
4451
u += (u >> 15) & KYBER_Q;
45-
t[j] = ((((uint32_t)u << 5) + KYBER_Q/2)/KYBER_Q) & 31;
52+
/* t[j] = ((((uint32_t)u << 5) + KYBER_Q/2)/KYBER_Q) & 31; */
53+
d0 = u << 5;
54+
d0 += 1664;
55+
d0 *= 40318;
56+
d0 >>= 27;
57+
t[j] = d0 & 0x1f;
4658
}
4759

4860
r[0] = (t[0] >> 0) | (t[1] << 5);

‎ref/polyvec.c‎

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
void polyvec_compress(uint8_t r[KYBER_POLYVECCOMPRESSEDBYTES], const polyvec *a)
1616
{
1717
unsigned int i,j,k;
18+
uint64_t d0;
1819

1920
#if (KYBER_POLYVECCOMPRESSEDBYTES == (KYBER_K * 352))
2021
uint16_t t[8];
@@ -23,7 +24,14 @@ void polyvec_compress(uint8_t r[KYBER_POLYVECCOMPRESSEDBYTES], const polyvec *a)
2324
for(k=0;k<8;k++) {
2425
t[k] = a->vec[i].coeffs[8*j+k];
2526
t[k] += ((int16_t)t[k] >> 15) & KYBER_Q;
26-
t[k] = ((((uint32_t)t[k] << 11) + KYBER_Q/2)/KYBER_Q) & 0x7ff;
27+
/* t[k] = ((((uint32_t)t[k] << 11) + KYBER_Q/2)/KYBER_Q) & 0x7ff; */
28+
d0 = t[k];
29+
d0 <<= 11;
30+
d0 += 1664;
31+
d0 *= 645084;
32+
d0 >>= 31;
33+
t[k] = d0 & 0x7ff;
34+
2735
}
2836

2937
r[ 0] = (t[0] >> 0);
@@ -47,7 +55,13 @@ void polyvec_compress(uint8_t r[KYBER_POLYVECCOMPRESSEDBYTES], const polyvec *a)
4755
for(k=0;k<4;k++) {
4856
t[k] = a->vec[i].coeffs[4*j+k];
4957
t[k] += ((int16_t)t[k] >> 15) & KYBER_Q;
50-
t[k] = ((((uint32_t)t[k] << 10) + KYBER_Q/2)/ KYBER_Q) & 0x3ff;
58+
/* t[k] = ((((uint32_t)t[k] << 10) + KYBER_Q/2)/ KYBER_Q) & 0x3ff; */
59+
d0 = t[k];
60+
d0 <<= 10;
61+
d0 += 1665;
62+
d0 *= 1290167;
63+
d0 >>= 32;
64+
t[k] = d0 & 0x3ff;
5165
}
5266

5367
r[0] = (t[0] >> 0);

‎ref/test/test_kyber.c‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
#define NTESTS 1000
88

9-
static int test_keys()
9+
static int test_keys(void)
1010
{
1111
uint8_t pk[CRYPTO_PUBLICKEYBYTES];
1212
uint8_t sk[CRYPTO_SECRETKEYBYTES];
@@ -31,7 +31,7 @@ static int test_keys()
3131
return 0;
3232
}
3333

34-
static int test_invalid_sk_a()
34+
static int test_invalid_sk_a(void)
3535
{
3636
uint8_t pk[CRYPTO_PUBLICKEYBYTES];
3737
uint8_t sk[CRYPTO_SECRETKEYBYTES];
@@ -59,7 +59,7 @@ static int test_invalid_sk_a()
5959
return 0;
6060
}
6161

62-
static int test_invalid_ciphertext()
62+
static int test_invalid_ciphertext(void)
6363
{
6464
uint8_t pk[CRYPTO_PUBLICKEYBYTES];
6565
uint8_t sk[CRYPTO_SECRETKEYBYTES];

‎ref/test/test_speed.c‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
uint64_t t[NTESTS];
1717
uint8_t seed[KYBER_SYMBYTES] = {0};
1818

19-
int main()
19+
int main(void)
2020
{
2121
unsigned int i;
2222
uint8_t pk[CRYPTO_PUBLICKEYBYTES];

‎runtests.sh‎

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,22 @@ else
1111
fi
1212

1313
if [ "$ARCH" = "amd64" -o "$ARCH" = "arm64" ]; then
14-
export CC=/usr/bin/clang
15-
export CFLAGS="-fsanitize=undefined,address ${CFLAGS}"
14+
export CC=/usr/bin/gcc
15+
# export CFLAGS="-fsanitize=undefined,address ${CFLAGS}"
1616
fi
1717

1818
for dir in $DIRS; do
1919
make -j$(nproc) -C $dir clean
2020
make -j$(nproc) -C $dir
2121
for alg in 512 768 1024; do
22-
#valgrind --vex-guest-max-insns=25 ./$dir/test_kyber$alg
23-
./$dir/test/test_kyber$alg &
24-
PID1=$!
25-
echo testvec$alg
26-
./$dir/test/test_vectors$alg > tvecs$alg &
27-
PID2=$!
28-
wait $PID1 $PID2
22+
valgrind --vex-guest-max-insns=25 ./$dir/test/test_kyber$alg
23+
echo test_kyber$alg
24+
./$dir/test/test_kyber$alg
25+
# PID1=$!
26+
# echo testvec$alg
27+
./$dir/test/test_vectors$alg > tvecs$alg
28+
# PID2=$!
29+
# wait $PID1 $PID2
2930
done
3031
shasum -a256 -c SHA256SUMS
3132
done

0 commit comments

Comments
 (0)