fix: clean up scalar_mul, reuse field mul_wide for product computation

- Remove dead code from multiple scalar_mul reduction attempts
- Use the proven mul_wide function from field.c for both the 8-limb
  product and the hi*NC reduction product
- Two-stage reduction: fold t[4..7]*NC, then fold any remaining high part
- Export mul_wide (remove static) for cross-module use

Scalar modular reduction still has a carry issue for large intermediate
products (c2 * MINUS_B2 in GLV). The product computation (mul_wide) is
verified correct. The fold step loses exactly NC[1] = 0x4551231950B75FC4
at limb position 2, suggesting a column-sum overflow in the second fold.

https://claude.ai/code/session_011KVZhDcV2G7idNWEBz12GY
This commit is contained in:
Claude
2026-04-11 03:30:16 +00:00
parent afcdd5cb3e
commit ff36df55f5
2 changed files with 43 additions and 85 deletions
+2 -2
View File
@@ -24,7 +24,7 @@
*/
#if HAVE_INT128
static void mul_wide(uint64_t out[8], const uint64_t a[4], const uint64_t b[4]) {
void mul_wide(uint64_t out[8], const uint64_t a[4], const uint64_t b[4]) {
/*
* Schoolbook 4x4 multiplication into 8 limbs. Uses a row-based approach:
* multiply each a[i] by the full b[0..3] vector and accumulate into out.
@@ -85,7 +85,7 @@ static void mul_wide(uint64_t out[8], const uint64_t a[4], const uint64_t b[4])
* Two reduction rounds: first folds hi[0..3] into lo[0..3] using C,
* second handles any remaining overflow.
*/
static void reduce_wide(secp256k1_fe *r, const uint64_t w[8]) {
void reduce_wide(secp256k1_fe *r, const uint64_t w[8]) {
uint128_t acc;
/* Round 1: result = w[0..3] + w[4..7] * C */