From 463434d1f7159780f64b0fe2ca4d042cb49f1b2a Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Thu, 26 Jul 2018 18:03:10 +0100 Subject: [PATCH] more comprehensive test for ge_p3 comparison to identity/point at infinity Reported by QuarksLab. --- src/crypto/crypto-ops.c | 13 +++++++++++++ src/crypto/crypto-ops.h | 2 ++ src/ringct/multiexp.cc | 12 ++++++------ 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/crypto/crypto-ops.c b/src/crypto/crypto-ops.c index c1fff1d44..09296d6f9 100644 --- a/src/crypto/crypto-ops.c +++ b/src/crypto/crypto-ops.c @@ -3729,3 +3729,16 @@ int sc_isnonzero(const unsigned char *s) { s[18] | s[19] | s[20] | s[21] | s[22] | s[23] | s[24] | s[25] | s[26] | s[27] | s[28] | s[29] | s[30] | s[31]) - 1) >> 8) + 1; } + +int ge_p3_is_point_at_infinity(const ge_p3 *p) { + // X = 0 and Y == Z + int n; + for (n = 0; n < 10; ++n) + { + if (p->X[n] | p->T[n]) + return 0; + if (p->Y[n] != p->Z[n]) + return 0; + } + return 1; +} diff --git a/src/crypto/crypto-ops.h b/src/crypto/crypto-ops.h index 52854889f..2910dafd4 100644 --- a/src/crypto/crypto-ops.h +++ b/src/crypto/crypto-ops.h @@ -159,3 +159,5 @@ void ge_sub(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q); void fe_add(fe h, const fe f, const fe g); void fe_tobytes(unsigned char *, const fe); void fe_invert(fe out, const fe z); + +int ge_p3_is_point_at_infinity(const ge_p3 *p); diff --git a/src/ringct/multiexp.cc b/src/ringct/multiexp.cc index 901b00edd..21957b94c 100644 --- a/src/ringct/multiexp.cc +++ b/src/ringct/multiexp.cc @@ -216,7 +216,7 @@ rct::key bos_coster_heap_conv_robust(std::vector data) heap.reserve(points); for (size_t n = 0; n < points; ++n) { - if (!(data[n].scalar == rct::zero()) && memcmp(&data[n].point, &ge_p3_identity, sizeof(ge_p3))) + if (!(data[n].scalar == rct::zero()) && !ge_p3_is_point_at_infinity(&data[n].point)) heap.push_back(n); } points = heap.size(); @@ -442,7 +442,7 @@ rct::key straus(const std::vector &data, const std::shared_ptr skip(data.size()); for (size_t i = 0; i < data.size(); ++i) - skip[i] = data[i].scalar == rct::zero() || !memcmp(&data[i].point, &ge_p3_identity, sizeof(ge_p3)); + skip[i] = data[i].scalar == rct::zero() || ge_p3_is_point_at_infinity(&data[i].point); MULTIEXP_PERF(PERF_TIMER_STOP(skip)); #endif @@ -611,7 +611,7 @@ rct::key pippenger(const std::vector &data, const std::shared_ptr< for (size_t k = groups; k-- > 0; ) { - if (memcmp(&result, &ge_p3_identity, sizeof(ge_p3))) + if (!ge_p3_is_point_at_infinity(&result)) { ge_p2 p2; ge_p3_to_p2(&p2, &result); @@ -638,7 +638,7 @@ rct::key pippenger(const std::vector &data, const std::shared_ptr< if (bucket == 0) continue; CHECK_AND_ASSERT_THROW_MES(bucket < (1u<cached[i]); } @@ -650,9 +650,9 @@ rct::key pippenger(const std::vector &data, const std::shared_ptr< ge_p3 pail = ge_p3_identity; for (size_t i = (1< 0; --i) { - if (memcmp(&buckets[i], &ge_p3_identity, sizeof(ge_p3))) + if (!ge_p3_is_point_at_infinity(&buckets[i])) add(pail, buckets[i]); - if (memcmp(&pail, &ge_p3_identity, sizeof(ge_p3))) + if (!ge_p3_is_point_at_infinity(&pail)) add(result, pail); } }