From 5f1d73bca01804214590441beb110d4da5b6b1d7 Mon Sep 17 00:00:00 2001 From: Henry de Valence Date: Wed, 5 Jun 2019 20:59:07 -0700 Subject: [PATCH] Fix a negate-with-overflow edgecase by widening before computation. This fixes a bug in the Pippenger implementation reported by Fernando Krell and diagnosed by Oleg Andreev. The problem is that at the largest problem sizes (using w=8), the signed digits fill the value range of an i8, and so doing computation on them to calculate the bucket index can hit an overflow. This was not caught in CI because the test suite didn't check all problem sizes; tests for these sizes which expose this bug were added in the previous commit. --- src/backend/serial/scalar_mul/pippenger.rs | 3 ++- src/backend/vector/scalar_mul/pippenger.rs | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/backend/serial/scalar_mul/pippenger.rs b/src/backend/serial/scalar_mul/pippenger.rs index 89ea723..5a028fd 100644 --- a/src/backend/serial/scalar_mul/pippenger.rs +++ b/src/backend/serial/scalar_mul/pippenger.rs @@ -125,7 +125,8 @@ impl VartimeMultiscalarMul for Pippenger { // Note: if we add support for precomputed lookup tables, // we'll be adding/subtracting point premultiplied by `digits[i]` to buckets[0]. for (digits, pt) in scalars_points.iter() { - let digit = digits[digit_index]; + // Widen digit so that we don't run into edge cases when w=8. + let digit = digits[digit_index] as i16; if digit > 0 { let b = (digit - 1) as usize; buckets[b] = (&buckets[b] + pt).to_extended(); diff --git a/src/backend/vector/scalar_mul/pippenger.rs b/src/backend/vector/scalar_mul/pippenger.rs index 0053e67..21d2d37 100644 --- a/src/backend/vector/scalar_mul/pippenger.rs +++ b/src/backend/vector/scalar_mul/pippenger.rs @@ -82,7 +82,8 @@ impl VartimeMultiscalarMul for Pippenger { // Note: if we add support for precomputed lookup tables, // we'll be adding/subtractiong point premultiplied by `digits[i]` to buckets[0]. for (digits, pt) in scalars_points.iter() { - let digit = digits[digit_index]; + // Widen digit so that we don't run into edge cases when w=8. + let digit = digits[digit_index] as i16; if digit > 0 { let b = (digit - 1) as usize; buckets[b] = &buckets[b] + pt;