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
This commit is contained in:
Claude
2026-04-11 03:37:44 +00:00
parent 8cf2f9795a
commit da3ed9ba3e
+7
View File
@@ -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; }