Skip to content

Commit 01b819a

Browse files
Merge #1158: Add a secp256k1_i128_to_u64 function.
d216475 test secp256k1_i128_to_i64 (Russell O'Connor) 4bc4290 Add a secp256k1_i128_to_u64 function. (Russell O'Connor) Pull request description: I wanted to experiment with what would be required to split up `secp256k1_i128_to_i64` between those cases when a signed 64 bit value is being demoted, versus an unsigned 64 bit value is being extracted from the lower bits, and this is the result. I'm not sure this is a useful PR, so feel free to close it. However, since it is already written, I figured it is worth at least discussing. ACKs for top commit: sipa: utACK d216475 real-or-random: ACK d216475 Tree-SHA512: 41dbb1d33b3078bee8e71a838cfad6f1859c0bba602ae061259add8e9e8ea5aa482daa41de79dbd7433ddbef4a0bc52757f3c45d63acc9c0eb05aa3ca891b922
2 parents eacad90 + d216475 commit 01b819a

5 files changed

+61
-43
lines changed

src/int128.h

+6-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,12 @@ static SECP256K1_INLINE void secp256k1_i128_det(secp256k1_int128 *r, int64_t a,
6666
*/
6767
static SECP256K1_INLINE void secp256k1_i128_rshift(secp256k1_int128 *r, unsigned int b);
6868

69-
/* Return the low 64-bits of a 128-bit value interpreted as an signed 64-bit value. */
69+
/* Return the input value modulo 2^64. */
70+
static SECP256K1_INLINE uint64_t secp256k1_i128_to_u64(const secp256k1_int128 *a);
71+
72+
/* Return the value as a signed 64-bit value.
73+
* Requires the input to be between INT64_MIN and INT64_MAX.
74+
*/
7075
static SECP256K1_INLINE int64_t secp256k1_i128_to_i64(const secp256k1_int128 *a);
7176

7277
/* Write a signed 64-bit value to r. */

src/int128_native_impl.h

+5
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,12 @@ static SECP256K1_INLINE void secp256k1_i128_rshift(secp256k1_int128 *r, unsigned
6767
*r >>= n;
6868
}
6969

70+
static SECP256K1_INLINE uint64_t secp256k1_i128_to_u64(const secp256k1_int128 *a) {
71+
return (uint64_t)*a;
72+
}
73+
7074
static SECP256K1_INLINE int64_t secp256k1_i128_to_i64(const secp256k1_int128 *a) {
75+
VERIFY_CHECK(INT64_MIN <= *a && *a <= INT64_MAX);
7176
return *a;
7277
}
7378

src/int128_struct_impl.h

+7-1
Original file line numberDiff line numberDiff line change
@@ -170,8 +170,14 @@ static SECP256K1_INLINE void secp256k1_i128_rshift(secp256k1_int128 *r, unsigned
170170
}
171171
}
172172

173+
static SECP256K1_INLINE uint64_t secp256k1_i128_to_u64(const secp256k1_int128 *a) {
174+
return a->lo;
175+
}
176+
173177
static SECP256K1_INLINE int64_t secp256k1_i128_to_i64(const secp256k1_int128 *a) {
174-
return (int64_t)a->lo;
178+
/* Verify that a represents a 64 bit signed value by checking that the high bits are a sign extension of the low bits. */
179+
VERIFY_CHECK(a->hi == -(a->lo >> 63));
180+
return (int64_t)secp256k1_i128_to_u64(a);
175181
}
176182

177183
static SECP256K1_INLINE void secp256k1_i128_from_i64(secp256k1_int128 *r, int64_t a) {

src/modinv64_impl.h

+33-33
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,13 @@ static const secp256k1_modinv64_signed62 SECP256K1_SIGNED62_ONE = {{1}};
3939

4040
/* Compute a*factor and put it in r. All but the top limb in r will be in range [0,2^62). */
4141
static void secp256k1_modinv64_mul_62(secp256k1_modinv64_signed62 *r, const secp256k1_modinv64_signed62 *a, int alen, int64_t factor) {
42-
const int64_t M62 = (int64_t)(UINT64_MAX >> 2);
42+
const uint64_t M62 = UINT64_MAX >> 2;
4343
secp256k1_int128 c, d;
4444
int i;
4545
secp256k1_i128_from_i64(&c, 0);
4646
for (i = 0; i < 4; ++i) {
4747
if (i < alen) secp256k1_i128_accum_mul(&c, a->v[i], factor);
48-
r->v[i] = secp256k1_i128_to_i64(&c) & M62; secp256k1_i128_rshift(&c, 62);
48+
r->v[i] = secp256k1_i128_to_u64(&c) & M62; secp256k1_i128_rshift(&c, 62);
4949
}
5050
if (4 < alen) secp256k1_i128_accum_mul(&c, a->v[4], factor);
5151
secp256k1_i128_from_i64(&d, secp256k1_i128_to_i64(&c));
@@ -314,7 +314,7 @@ static int64_t secp256k1_modinv64_divsteps_62_var(int64_t eta, uint64_t f0, uint
314314
* This implements the update_de function from the explanation.
315315
*/
316316
static void secp256k1_modinv64_update_de_62(secp256k1_modinv64_signed62 *d, secp256k1_modinv64_signed62 *e, const secp256k1_modinv64_trans2x2 *t, const secp256k1_modinv64_modinfo* modinfo) {
317-
const int64_t M62 = (int64_t)(UINT64_MAX >> 2);
317+
const uint64_t M62 = UINT64_MAX >> 2;
318318
const int64_t d0 = d->v[0], d1 = d->v[1], d2 = d->v[2], d3 = d->v[3], d4 = d->v[4];
319319
const int64_t e0 = e->v[0], e1 = e->v[1], e2 = e->v[2], e3 = e->v[3], e4 = e->v[4];
320320
const int64_t u = t->u, v = t->v, q = t->q, r = t->r;
@@ -327,8 +327,8 @@ static void secp256k1_modinv64_update_de_62(secp256k1_modinv64_signed62 *d, secp
327327
VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(e, 5, &modinfo->modulus, 1) < 0); /* e < modulus */
328328
VERIFY_CHECK((secp256k1_modinv64_abs(u) + secp256k1_modinv64_abs(v)) >= 0); /* |u|+|v| doesn't overflow */
329329
VERIFY_CHECK((secp256k1_modinv64_abs(q) + secp256k1_modinv64_abs(r)) >= 0); /* |q|+|r| doesn't overflow */
330-
VERIFY_CHECK((secp256k1_modinv64_abs(u) + secp256k1_modinv64_abs(v)) <= M62 + 1); /* |u|+|v| <= 2^62 */
331-
VERIFY_CHECK((secp256k1_modinv64_abs(q) + secp256k1_modinv64_abs(r)) <= M62 + 1); /* |q|+|r| <= 2^62 */
330+
VERIFY_CHECK((secp256k1_modinv64_abs(u) + secp256k1_modinv64_abs(v)) <= (int64_t)1 << 62); /* |u|+|v| <= 2^62 */
331+
VERIFY_CHECK((secp256k1_modinv64_abs(q) + secp256k1_modinv64_abs(r)) <= (int64_t)1 << 62); /* |q|+|r| <= 2^62 */
332332
#endif
333333
/* [md,me] start as zero; plus [u,q] if d is negative; plus [v,r] if e is negative. */
334334
sd = d4 >> 63;
@@ -341,14 +341,14 @@ static void secp256k1_modinv64_update_de_62(secp256k1_modinv64_signed62 *d, secp
341341
secp256k1_i128_mul(&ce, q, d0);
342342
secp256k1_i128_accum_mul(&ce, r, e0);
343343
/* Correct md,me so that t*[d,e]+modulus*[md,me] has 62 zero bottom bits. */
344-
md -= (modinfo->modulus_inv62 * (uint64_t)secp256k1_i128_to_i64(&cd) + md) & M62;
345-
me -= (modinfo->modulus_inv62 * (uint64_t)secp256k1_i128_to_i64(&ce) + me) & M62;
344+
md -= (modinfo->modulus_inv62 * secp256k1_i128_to_u64(&cd) + md) & M62;
345+
me -= (modinfo->modulus_inv62 * secp256k1_i128_to_u64(&ce) + me) & M62;
346346
/* Update the beginning of computation for t*[d,e]+modulus*[md,me] now md,me are known. */
347347
secp256k1_i128_accum_mul(&cd, modinfo->modulus.v[0], md);
348348
secp256k1_i128_accum_mul(&ce, modinfo->modulus.v[0], me);
349349
/* Verify that the low 62 bits of the computation are indeed zero, and then throw them away. */
350-
VERIFY_CHECK((secp256k1_i128_to_i64(&cd) & M62) == 0); secp256k1_i128_rshift(&cd, 62);
351-
VERIFY_CHECK((secp256k1_i128_to_i64(&ce) & M62) == 0); secp256k1_i128_rshift(&ce, 62);
350+
VERIFY_CHECK((secp256k1_i128_to_u64(&cd) & M62) == 0); secp256k1_i128_rshift(&cd, 62);
351+
VERIFY_CHECK((secp256k1_i128_to_u64(&ce) & M62) == 0); secp256k1_i128_rshift(&ce, 62);
352352
/* Compute limb 1 of t*[d,e]+modulus*[md,me], and store it as output limb 0 (= down shift). */
353353
secp256k1_i128_accum_mul(&cd, u, d1);
354354
secp256k1_i128_accum_mul(&cd, v, e1);
@@ -358,8 +358,8 @@ static void secp256k1_modinv64_update_de_62(secp256k1_modinv64_signed62 *d, secp
358358
secp256k1_i128_accum_mul(&cd, modinfo->modulus.v[1], md);
359359
secp256k1_i128_accum_mul(&ce, modinfo->modulus.v[1], me);
360360
}
361-
d->v[0] = secp256k1_i128_to_i64(&cd) & M62; secp256k1_i128_rshift(&cd, 62);
362-
e->v[0] = secp256k1_i128_to_i64(&ce) & M62; secp256k1_i128_rshift(&ce, 62);
361+
d->v[0] = secp256k1_i128_to_u64(&cd) & M62; secp256k1_i128_rshift(&cd, 62);
362+
e->v[0] = secp256k1_i128_to_u64(&ce) & M62; secp256k1_i128_rshift(&ce, 62);
363363
/* Compute limb 2 of t*[d,e]+modulus*[md,me], and store it as output limb 1. */
364364
secp256k1_i128_accum_mul(&cd, u, d2);
365365
secp256k1_i128_accum_mul(&cd, v, e2);
@@ -369,8 +369,8 @@ static void secp256k1_modinv64_update_de_62(secp256k1_modinv64_signed62 *d, secp
369369
secp256k1_i128_accum_mul(&cd, modinfo->modulus.v[2], md);
370370
secp256k1_i128_accum_mul(&ce, modinfo->modulus.v[2], me);
371371
}
372-
d->v[1] = secp256k1_i128_to_i64(&cd) & M62; secp256k1_i128_rshift(&cd, 62);
373-
e->v[1] = secp256k1_i128_to_i64(&ce) & M62; secp256k1_i128_rshift(&ce, 62);
372+
d->v[1] = secp256k1_i128_to_u64(&cd) & M62; secp256k1_i128_rshift(&cd, 62);
373+
e->v[1] = secp256k1_i128_to_u64(&ce) & M62; secp256k1_i128_rshift(&ce, 62);
374374
/* Compute limb 3 of t*[d,e]+modulus*[md,me], and store it as output limb 2. */
375375
secp256k1_i128_accum_mul(&cd, u, d3);
376376
secp256k1_i128_accum_mul(&cd, v, e3);
@@ -380,17 +380,17 @@ static void secp256k1_modinv64_update_de_62(secp256k1_modinv64_signed62 *d, secp
380380
secp256k1_i128_accum_mul(&cd, modinfo->modulus.v[3], md);
381381
secp256k1_i128_accum_mul(&ce, modinfo->modulus.v[3], me);
382382
}
383-
d->v[2] = secp256k1_i128_to_i64(&cd) & M62; secp256k1_i128_rshift(&cd, 62);
384-
e->v[2] = secp256k1_i128_to_i64(&ce) & M62; secp256k1_i128_rshift(&ce, 62);
383+
d->v[2] = secp256k1_i128_to_u64(&cd) & M62; secp256k1_i128_rshift(&cd, 62);
384+
e->v[2] = secp256k1_i128_to_u64(&ce) & M62; secp256k1_i128_rshift(&ce, 62);
385385
/* Compute limb 4 of t*[d,e]+modulus*[md,me], and store it as output limb 3. */
386386
secp256k1_i128_accum_mul(&cd, u, d4);
387387
secp256k1_i128_accum_mul(&cd, v, e4);
388388
secp256k1_i128_accum_mul(&ce, q, d4);
389389
secp256k1_i128_accum_mul(&ce, r, e4);
390390
secp256k1_i128_accum_mul(&cd, modinfo->modulus.v[4], md);
391391
secp256k1_i128_accum_mul(&ce, modinfo->modulus.v[4], me);
392-
d->v[3] = secp256k1_i128_to_i64(&cd) & M62; secp256k1_i128_rshift(&cd, 62);
393-
e->v[3] = secp256k1_i128_to_i64(&ce) & M62; secp256k1_i128_rshift(&ce, 62);
392+
d->v[3] = secp256k1_i128_to_u64(&cd) & M62; secp256k1_i128_rshift(&cd, 62);
393+
e->v[3] = secp256k1_i128_to_u64(&ce) & M62; secp256k1_i128_rshift(&ce, 62);
394394
/* What remains is limb 5 of t*[d,e]+modulus*[md,me]; store it as output limb 4. */
395395
d->v[4] = secp256k1_i128_to_i64(&cd);
396396
e->v[4] = secp256k1_i128_to_i64(&ce);
@@ -407,7 +407,7 @@ static void secp256k1_modinv64_update_de_62(secp256k1_modinv64_signed62 *d, secp
407407
* This implements the update_fg function from the explanation.
408408
*/
409409
static void secp256k1_modinv64_update_fg_62(secp256k1_modinv64_signed62 *f, secp256k1_modinv64_signed62 *g, const secp256k1_modinv64_trans2x2 *t) {
410-
const int64_t M62 = (int64_t)(UINT64_MAX >> 2);
410+
const uint64_t M62 = UINT64_MAX >> 2;
411411
const int64_t f0 = f->v[0], f1 = f->v[1], f2 = f->v[2], f3 = f->v[3], f4 = f->v[4];
412412
const int64_t g0 = g->v[0], g1 = g->v[1], g2 = g->v[2], g3 = g->v[3], g4 = g->v[4];
413413
const int64_t u = t->u, v = t->v, q = t->q, r = t->r;
@@ -418,36 +418,36 @@ static void secp256k1_modinv64_update_fg_62(secp256k1_modinv64_signed62 *f, secp
418418
secp256k1_i128_mul(&cg, q, f0);
419419
secp256k1_i128_accum_mul(&cg, r, g0);
420420
/* Verify that the bottom 62 bits of the result are zero, and then throw them away. */
421-
VERIFY_CHECK((secp256k1_i128_to_i64(&cf) & M62) == 0); secp256k1_i128_rshift(&cf, 62);
422-
VERIFY_CHECK((secp256k1_i128_to_i64(&cg) & M62) == 0); secp256k1_i128_rshift(&cg, 62);
421+
VERIFY_CHECK((secp256k1_i128_to_u64(&cf) & M62) == 0); secp256k1_i128_rshift(&cf, 62);
422+
VERIFY_CHECK((secp256k1_i128_to_u64(&cg) & M62) == 0); secp256k1_i128_rshift(&cg, 62);
423423
/* Compute limb 1 of t*[f,g], and store it as output limb 0 (= down shift). */
424424
secp256k1_i128_accum_mul(&cf, u, f1);
425425
secp256k1_i128_accum_mul(&cf, v, g1);
426426
secp256k1_i128_accum_mul(&cg, q, f1);
427427
secp256k1_i128_accum_mul(&cg, r, g1);
428-
f->v[0] = secp256k1_i128_to_i64(&cf) & M62; secp256k1_i128_rshift(&cf, 62);
429-
g->v[0] = secp256k1_i128_to_i64(&cg) & M62; secp256k1_i128_rshift(&cg, 62);
428+
f->v[0] = secp256k1_i128_to_u64(&cf) & M62; secp256k1_i128_rshift(&cf, 62);
429+
g->v[0] = secp256k1_i128_to_u64(&cg) & M62; secp256k1_i128_rshift(&cg, 62);
430430
/* Compute limb 2 of t*[f,g], and store it as output limb 1. */
431431
secp256k1_i128_accum_mul(&cf, u, f2);
432432
secp256k1_i128_accum_mul(&cf, v, g2);
433433
secp256k1_i128_accum_mul(&cg, q, f2);
434434
secp256k1_i128_accum_mul(&cg, r, g2);
435-
f->v[1] = secp256k1_i128_to_i64(&cf) & M62; secp256k1_i128_rshift(&cf, 62);
436-
g->v[1] = secp256k1_i128_to_i64(&cg) & M62; secp256k1_i128_rshift(&cg, 62);
435+
f->v[1] = secp256k1_i128_to_u64(&cf) & M62; secp256k1_i128_rshift(&cf, 62);
436+
g->v[1] = secp256k1_i128_to_u64(&cg) & M62; secp256k1_i128_rshift(&cg, 62);
437437
/* Compute limb 3 of t*[f,g], and store it as output limb 2. */
438438
secp256k1_i128_accum_mul(&cf, u, f3);
439439
secp256k1_i128_accum_mul(&cf, v, g3);
440440
secp256k1_i128_accum_mul(&cg, q, f3);
441441
secp256k1_i128_accum_mul(&cg, r, g3);
442-
f->v[2] = secp256k1_i128_to_i64(&cf) & M62; secp256k1_i128_rshift(&cf, 62);
443-
g->v[2] = secp256k1_i128_to_i64(&cg) & M62; secp256k1_i128_rshift(&cg, 62);
442+
f->v[2] = secp256k1_i128_to_u64(&cf) & M62; secp256k1_i128_rshift(&cf, 62);
443+
g->v[2] = secp256k1_i128_to_u64(&cg) & M62; secp256k1_i128_rshift(&cg, 62);
444444
/* Compute limb 4 of t*[f,g], and store it as output limb 3. */
445445
secp256k1_i128_accum_mul(&cf, u, f4);
446446
secp256k1_i128_accum_mul(&cf, v, g4);
447447
secp256k1_i128_accum_mul(&cg, q, f4);
448448
secp256k1_i128_accum_mul(&cg, r, g4);
449-
f->v[3] = secp256k1_i128_to_i64(&cf) & M62; secp256k1_i128_rshift(&cf, 62);
450-
g->v[3] = secp256k1_i128_to_i64(&cg) & M62; secp256k1_i128_rshift(&cg, 62);
449+
f->v[3] = secp256k1_i128_to_u64(&cf) & M62; secp256k1_i128_rshift(&cf, 62);
450+
g->v[3] = secp256k1_i128_to_u64(&cg) & M62; secp256k1_i128_rshift(&cg, 62);
451451
/* What remains is limb 5 of t*[f,g]; store it as output limb 4. */
452452
f->v[4] = secp256k1_i128_to_i64(&cf);
453453
g->v[4] = secp256k1_i128_to_i64(&cg);
@@ -460,7 +460,7 @@ static void secp256k1_modinv64_update_fg_62(secp256k1_modinv64_signed62 *f, secp
460460
* This implements the update_fg function from the explanation.
461461
*/
462462
static void secp256k1_modinv64_update_fg_62_var(int len, secp256k1_modinv64_signed62 *f, secp256k1_modinv64_signed62 *g, const secp256k1_modinv64_trans2x2 *t) {
463-
const int64_t M62 = (int64_t)(UINT64_MAX >> 2);
463+
const uint64_t M62 = UINT64_MAX >> 2;
464464
const int64_t u = t->u, v = t->v, q = t->q, r = t->r;
465465
int64_t fi, gi;
466466
secp256k1_int128 cf, cg;
@@ -474,8 +474,8 @@ static void secp256k1_modinv64_update_fg_62_var(int len, secp256k1_modinv64_sign
474474
secp256k1_i128_mul(&cg, q, fi);
475475
secp256k1_i128_accum_mul(&cg, r, gi);
476476
/* Verify that the bottom 62 bits of the result are zero, and then throw them away. */
477-
VERIFY_CHECK((secp256k1_i128_to_i64(&cf) & M62) == 0); secp256k1_i128_rshift(&cf, 62);
478-
VERIFY_CHECK((secp256k1_i128_to_i64(&cg) & M62) == 0); secp256k1_i128_rshift(&cg, 62);
477+
VERIFY_CHECK((secp256k1_i128_to_u64(&cf) & M62) == 0); secp256k1_i128_rshift(&cf, 62);
478+
VERIFY_CHECK((secp256k1_i128_to_u64(&cg) & M62) == 0); secp256k1_i128_rshift(&cg, 62);
479479
/* Now iteratively compute limb i=1..len of t*[f,g], and store them in output limb i-1 (shifting
480480
* down by 62 bits). */
481481
for (i = 1; i < len; ++i) {
@@ -485,8 +485,8 @@ static void secp256k1_modinv64_update_fg_62_var(int len, secp256k1_modinv64_sign
485485
secp256k1_i128_accum_mul(&cf, v, gi);
486486
secp256k1_i128_accum_mul(&cg, q, fi);
487487
secp256k1_i128_accum_mul(&cg, r, gi);
488-
f->v[i - 1] = secp256k1_i128_to_i64(&cf) & M62; secp256k1_i128_rshift(&cf, 62);
489-
g->v[i - 1] = secp256k1_i128_to_i64(&cg) & M62; secp256k1_i128_rshift(&cg, 62);
488+
f->v[i - 1] = secp256k1_i128_to_u64(&cf) & M62; secp256k1_i128_rshift(&cf, 62);
489+
g->v[i - 1] = secp256k1_i128_to_u64(&cg) & M62; secp256k1_i128_rshift(&cg, 62);
490490
}
491491
/* What remains is limb (len) of t*[f,g]; store it as output limb (len-1). */
492492
f->v[len - 1] = secp256k1_i128_to_i64(&cf);

src/tests.c

+10-8
Original file line numberDiff line numberDiff line change
@@ -1781,7 +1781,7 @@ void load256i128(uint16_t* out, const secp256k1_int128* v) {
17811781
uint64_t lo;
17821782
int64_t hi;
17831783
secp256k1_int128 c = *v;
1784-
lo = secp256k1_i128_to_i64(&c);
1784+
lo = secp256k1_i128_to_u64(&c);
17851785
secp256k1_i128_rshift(&c, 64);
17861786
hi = secp256k1_i128_to_i64(&c);
17871787
load256two64(out, hi, lo, 1);
@@ -1898,12 +1898,14 @@ void run_int128_test_case(void) {
18981898
secp256k1_i128_rshift(&swz, uc % 127);
18991899
load256i128(rswz, &swz);
19001900
CHECK(secp256k1_memcmp_var(rswr, rswz, 16) == 0);
1901-
/* test secp256k1_i128_to_i64 */
1902-
CHECK((uint64_t)secp256k1_i128_to_i64(&swa) == v[0]);
1901+
/* test secp256k1_i128_to_u64 */
1902+
CHECK(secp256k1_i128_to_u64(&swa) == v[0]);
19031903
/* test secp256k1_i128_from_i64 */
19041904
secp256k1_i128_from_i64(&swz, sb);
19051905
load256i128(rswz, &swz);
19061906
CHECK(secp256k1_memcmp_var(rsb, rswz, 16) == 0);
1907+
/* test secp256k1_i128_to_i64 */
1908+
CHECK(secp256k1_i128_to_i64(&swz) == sb);
19071909
/* test secp256k1_i128_eq_var */
19081910
{
19091911
int expect = (uc & 1);
@@ -1963,20 +1965,20 @@ void run_int128_tests(void) {
19631965
/* Compute INT128_MAX = 2^127 - 1 with secp256k1_i128_accum_mul */
19641966
secp256k1_i128_mul(&res, INT64_MAX, INT64_MAX);
19651967
secp256k1_i128_accum_mul(&res, INT64_MAX, INT64_MAX);
1966-
CHECK(secp256k1_i128_to_i64(&res) == 2);
1968+
CHECK(secp256k1_i128_to_u64(&res) == 2);
19671969
secp256k1_i128_accum_mul(&res, 4, 9223372036854775807);
19681970
secp256k1_i128_accum_mul(&res, 1, 1);
1969-
CHECK((uint64_t)secp256k1_i128_to_i64(&res) == UINT64_MAX);
1971+
CHECK(secp256k1_i128_to_u64(&res) == UINT64_MAX);
19701972
secp256k1_i128_rshift(&res, 64);
19711973
CHECK(secp256k1_i128_to_i64(&res) == INT64_MAX);
19721974

19731975
/* Compute INT128_MIN = - 2^127 with secp256k1_i128_accum_mul */
19741976
secp256k1_i128_mul(&res, INT64_MAX, INT64_MIN);
1975-
CHECK(secp256k1_i128_to_i64(&res) == INT64_MIN);
1977+
CHECK(secp256k1_i128_to_u64(&res) == (uint64_t)INT64_MIN);
19761978
secp256k1_i128_accum_mul(&res, INT64_MAX, INT64_MIN);
1977-
CHECK(secp256k1_i128_to_i64(&res) == 0);
1979+
CHECK(secp256k1_i128_to_u64(&res) == 0);
19781980
secp256k1_i128_accum_mul(&res, 2, INT64_MIN);
1979-
CHECK(secp256k1_i128_to_i64(&res) == 0);
1981+
CHECK(secp256k1_i128_to_u64(&res) == 0);
19801982
secp256k1_i128_rshift(&res, 64);
19811983
CHECK(secp256k1_i128_to_i64(&res) == INT64_MIN);
19821984
}

0 commit comments

Comments
 (0)