From da3ed9ba3ed4b01daa54fdaacca8833e8598f7ea Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 11 Apr 2026 03:37:44 +0000 Subject: [PATCH] fix: add aliasing protection to gej_add_ge and gej_add Both gej_add_ge(r, p, q) and gej_add(r, p, q) write to r->x/y/z while reading from p->x/y/z. When r == p (in-place accumulation in ecmult loops), the output overwrites input during computation. Added copy-on-alias detection at the top of both functions, matching the fix already applied to gej_double. https://claude.ai/code/session_011KVZhDcV2G7idNWEBz12GY --- quartz/src/main/c/secp256k1/point.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/quartz/src/main/c/secp256k1/point.c b/quartz/src/main/c/secp256k1/point.c index 7379e7f8d..e0c96c9af 100644 --- a/quartz/src/main/c/secp256k1/point.c +++ b/quartz/src/main/c/secp256k1/point.c @@ -119,6 +119,9 @@ void gej_double(secp256k1_gej *r, const secp256k1_gej *p) { /* Mixed addition: r = p + q where q is affine (Z=1). 8M + 3S */ void gej_add_ge(secp256k1_gej *r, const secp256k1_gej *p, const secp256k1_ge *q) { + /* Handle aliasing: if r == p, copy input first */ + secp256k1_gej tmp; + if (r == p) { tmp = *p; p = &tmp; } secp256k1_fe z12, z13, u2, s2, h, h2, i, j, rr, v, t; if (p->infinity) { @@ -196,6 +199,10 @@ void gej_add_ge(secp256k1_gej *r, const secp256k1_gej *p, const secp256k1_ge *q) /* Full Jacobian addition: r = p + q (11M + 5S) */ void gej_add(secp256k1_gej *r, const secp256k1_gej *p, const secp256k1_gej *q) { + /* Handle aliasing */ + secp256k1_gej tp, tq; + if (r == p) { tp = *p; p = &tp; } + if (r == q) { tq = *q; q = &tq; } secp256k1_fe z12, z22, u1, u2, s1, s2, h, h2, i, j, rr, v, t; if (p->infinity) { *r = *q; return; }