Skip to content

Commit 3ec478f

Browse files
committed
poly1305: Fix reduction step in Unreduced130::reduce
Fixes all remaining fuzzer crashes and test vectors.
1 parent 260f874 commit 3ec478f

2 files changed

Lines changed: 12 additions & 2 deletions

File tree

poly1305/src/avx2/helpers.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -501,7 +501,7 @@ impl Unreduced130 {
501501
// t = [0, 0, 0, t_4 >> 26]
502502
let t = _mm256_srlv_epi64(v1, _mm256_set_epi64x(64, 64, 64, 26));
503503
// v0 + 5·t = [t_3, t_2, t_1, t_0 + 5·(t_4 >> 26)]
504-
let red_0 = _mm256_add_epi64(_mm256_add_epi64(v0, t), _mm256_slli_epi32(t, 2));
504+
let red_0 = _mm256_add_epi64(_mm256_add_epi64(v0, t), _mm256_slli_epi64(t, 2));
505505
// [0, 0, 0, t_4 % 2^26]
506506
let red_1 = _mm256_and_si256(v1, _mm256_set_epi64x(0, 0, 0, 0x3ffffff));
507507
(red_1, red_0)

poly1305/src/fuzz.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,17 @@ fn crash_3() {
4848
// difference = 0x0100000000
4949
//
5050
// This discrepancy was due to Unreduced130::reduce (as called during finalization)
51-
// not correctly reducing. TODO: Figure out what about it was wrong.
51+
// not correctly reducing. During the reduction step, the upper limb's upper bits
52+
// (beyond 2^130) are added into the lower limb multiplied by 5 (for reduction modulo
53+
// 2^130 - 5). This is computed like so:
54+
//
55+
// b = t_4 >> 26
56+
// t_0 += b + (b << 2)
57+
//
58+
// It is possible for the upper limb to be 57+ bits; thus b << 2 can be 33+ bits.
59+
// However, the original reduction code was using _mm256_slli_epi32, which shifts
60+
// packed 32-bit integers; this was causing the upper bits of b to be lost. Switching
61+
// to _mm256_slli_epi64 (correctly treating b as a 64-bit field) solves the problem.
5262
avx2_fuzzer_test_case(include_bytes!(
5363
"fuzz/id:000003,sig:06,src:000003,op:havoc,rep:64"
5464
));

0 commit comments

Comments
 (0)