Skip to content

Commit b6d109d

Browse files
committed
Add _fe_half and use in _gej_add_ge
- Trades 1 _half for 3 _mul_int and 2 _normalize_weak
1 parent be6944a commit b6d109d

File tree

4 files changed

+74
-9
lines changed

4 files changed

+74
-9
lines changed

src/field.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,4 +124,6 @@ static void secp256k1_fe_storage_cmov(secp256k1_fe_storage *r, const secp256k1_f
124124
/** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. Both *r and *a must be initialized.*/
125125
static void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag);
126126

127+
static void secp256k1_fe_half(secp256k1_fe *r);
128+
127129
#endif /* SECP256K1_FIELD_H */

src/field_10x26_impl.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1120,6 +1120,45 @@ static SECP256K1_INLINE void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_
11201120
#endif
11211121
}
11221122

1123+
static SECP256K1_INLINE void secp256k1_fe_half(secp256k1_fe *r) {
1124+
uint32_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4],
1125+
t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8], t9 = r->n[9];
1126+
uint32_t one = (uint32_t)1;
1127+
uint32_t mask = -(t0 & one) >> 6;
1128+
1129+
#ifdef VERIFY
1130+
secp256k1_fe_verify(r);
1131+
#endif
1132+
1133+
t0 += 0x3FFFC2FUL & mask;
1134+
t1 += 0x3FFFFBFUL & mask;
1135+
t2 += mask;
1136+
t3 += mask;
1137+
t4 += mask;
1138+
t5 += mask;
1139+
t6 += mask;
1140+
t7 += mask;
1141+
t8 += mask;
1142+
t9 += mask >> 4;
1143+
1144+
r->n[0] = (t0 >> 1) + ((t1 & one) << 25);
1145+
r->n[1] = (t1 >> 1) + ((t2 & one) << 25);
1146+
r->n[2] = (t2 >> 1) + ((t3 & one) << 25);
1147+
r->n[3] = (t3 >> 1) + ((t4 & one) << 25);
1148+
r->n[4] = (t4 >> 1) + ((t5 & one) << 25);
1149+
r->n[5] = (t5 >> 1) + ((t6 & one) << 25);
1150+
r->n[6] = (t6 >> 1) + ((t7 & one) << 25);
1151+
r->n[7] = (t7 >> 1) + ((t8 & one) << 25);
1152+
r->n[8] = (t8 >> 1) + ((t9 & one) << 25);
1153+
r->n[9] = (t9 >> 1);
1154+
1155+
#ifdef VERIFY
1156+
r->magnitude = (r->magnitude >> 1) + 1;
1157+
r->normalized = 0;
1158+
secp256k1_fe_verify(r);
1159+
#endif
1160+
}
1161+
11231162
static SECP256K1_INLINE void secp256k1_fe_storage_cmov(secp256k1_fe_storage *r, const secp256k1_fe_storage *a, int flag) {
11241163
uint32_t mask0, mask1;
11251164
VG_CHECK_VERIFY(r->n, sizeof(r->n));

src/field_5x52_impl.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,34 @@ static SECP256K1_INLINE void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_
467467
#endif
468468
}
469469

470+
static SECP256K1_INLINE void secp256k1_fe_half(secp256k1_fe *r) {
471+
uint64_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4];
472+
uint64_t one = (uint64_t)1;
473+
uint64_t mask = -(t0 & one) >> 12;
474+
475+
#ifdef VERIFY
476+
secp256k1_fe_verify(r);
477+
#endif
478+
479+
t0 += 0xFFFFEFFFFFC2FULL & mask;
480+
t1 += mask;
481+
t2 += mask;
482+
t3 += mask;
483+
t4 += mask >> 4;
484+
485+
r->n[0] = (t0 >> 1) + ((t1 & one) << 51);
486+
r->n[1] = (t1 >> 1) + ((t2 & one) << 51);
487+
r->n[2] = (t2 >> 1) + ((t3 & one) << 51);
488+
r->n[3] = (t3 >> 1) + ((t4 & one) << 51);
489+
r->n[4] = (t4 >> 1);
490+
491+
#ifdef VERIFY
492+
r->magnitude = (r->magnitude >> 1) + 1;
493+
r->normalized = 0;
494+
secp256k1_fe_verify(r);
495+
#endif
496+
}
497+
470498
static SECP256K1_INLINE void secp256k1_fe_storage_cmov(secp256k1_fe_storage *r, const secp256k1_fe_storage *a, int flag) {
471499
uint64_t mask0, mask1;
472500
VG_CHECK_VERIFY(r->n, sizeof(r->n));

src/group_impl.h

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -593,19 +593,15 @@ static void secp256k1_gej_add_ge(secp256k1_gej *r, const secp256k1_gej *a, const
593593
secp256k1_fe_sqr(&t, &rr_alt); /* t = Ralt^2 (1) */
594594
secp256k1_fe_mul(&r->z, &a->z, &m_alt); /* r->z = Malt*Z (1) */
595595
infinity = secp256k1_fe_normalizes_to_zero(&r->z) & ~a->infinity;
596-
secp256k1_fe_mul_int(&r->z, 2); /* r->z = Z3 = 2*Malt*Z (2) */
597596
secp256k1_fe_negate(&q, &q, 1); /* q = -Q (2) */
598597
secp256k1_fe_add(&t, &q); /* t = Ralt^2-Q (3) */
599-
secp256k1_fe_normalize_weak(&t);
600-
r->x = t; /* r->x = Ralt^2-Q (1) */
601-
secp256k1_fe_mul_int(&t, 2); /* t = 2*x3 (2) */
602-
secp256k1_fe_add(&t, &q); /* t = 2*x3 - Q: (4) */
598+
r->x = t; /* r->x = Ralt^2-Q (3) */
599+
secp256k1_fe_mul_int(&t, 2); /* t = 2*x3 (6) */
600+
secp256k1_fe_add(&t, &q); /* t = 2*x3 - Q: (8) */
603601
secp256k1_fe_mul(&t, &t, &rr_alt); /* t = Ralt*(2*x3 - Q) (1) */
604602
secp256k1_fe_add(&t, &n); /* t = Ralt*(2*x3 - Q) + M^3*Malt (3) */
605-
secp256k1_fe_negate(&r->y, &t, 3); /* r->y = Ralt*(Q - 2x3) - M^3*Malt (4) */
606-
secp256k1_fe_normalize_weak(&r->y);
607-
secp256k1_fe_mul_int(&r->x, 4); /* r->x = X3 = 4*(Ralt^2-Q) */
608-
secp256k1_fe_mul_int(&r->y, 4); /* r->y = Y3 = 4*Ralt*(Q - 2x3) - 4*M^3*Malt (4) */
603+
secp256k1_fe_negate(&r->y, &t, 3); /* r->y = Ralt*(Q - 2*x3) - M^3*Malt (4) */
604+
secp256k1_fe_half(&r->y); /* r->y = (Ralt*(Q - 2*x3) - M^3*Malt)/2 (3) */
609605

610606
/** In case a->infinity == 1, replace r with (b->x, b->y, 1). */
611607
secp256k1_fe_cmov(&r->x, &b->x, a->infinity);

0 commit comments

Comments
 (0)