aboutsummaryrefslogtreecommitdiff
path: root/src/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'src/crypto')
-rw-r--r--src/crypto/crypto-ops.c50
-rw-r--r--src/crypto/crypto-ops.h2
-rw-r--r--src/crypto/crypto.h11
-rw-r--r--src/crypto/rx-slow-hash.c5
4 files changed, 58 insertions, 10 deletions
diff --git a/src/crypto/crypto-ops.c b/src/crypto/crypto-ops.c
index 508709280..54ca39775 100644
--- a/src/crypto/crypto-ops.c
+++ b/src/crypto/crypto-ops.c
@@ -3830,15 +3830,51 @@ int sc_isnonzero(const unsigned char *s) {
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)
+int ge_p3_is_point_at_infinity_vartime(const ge_p3 *p) {
+ // https://eprint.iacr.org/2008/522
+ // X == T == 0 and Y/Z == 1
+ // note: convert all pieces to canonical bytes in case rounding is required (i.e. an element is > q)
+ // note2: even though T = XY/Z is true for valid point representations (implying it isn't necessary to
+ // test T == 0), the input to this function might NOT be valid, so we must test T == 0
+ char result_X_bytes[32];
+ fe_tobytes((unsigned char*)&result_X_bytes, p->X);
+
+ // X != 0
+ for (int i = 0; i < 32; ++i)
{
- if (p->X[n] | p->T[n])
+ if (result_X_bytes[i])
return 0;
- if (p->Y[n] != p->Z[n])
+ }
+
+ char result_T_bytes[32];
+ fe_tobytes((unsigned char*)&result_T_bytes, p->T);
+
+ // T != 0
+ for (int i = 0; i < 32; ++i)
+ {
+ if (result_T_bytes[i])
+ return 0;
+ }
+
+ char result_Y_bytes[32];
+ char result_Z_bytes[32];
+ fe_tobytes((unsigned char*)&result_Y_bytes, p->Y);
+ fe_tobytes((unsigned char*)&result_Z_bytes, p->Z);
+
+ // Y != Z
+ for (int i = 0; i < 32; ++i)
+ {
+ if (result_Y_bytes[i] != result_Z_bytes[i])
return 0;
}
- return 1;
+
+ // is Y nonzero? then Y/Z == 1
+ for (int i = 0; i < 32; ++i)
+ {
+ if (result_Y_bytes[i] != 0)
+ return 1;
+ }
+
+ // Y/Z = 0/0
+ return 0;
}
diff --git a/src/crypto/crypto-ops.h b/src/crypto/crypto-ops.h
index 22f76974b..96da16cbd 100644
--- a/src/crypto/crypto-ops.h
+++ b/src/crypto/crypto-ops.h
@@ -162,4 +162,4 @@ 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);
+int ge_p3_is_point_at_infinity_vartime(const ge_p3 *p);
diff --git a/src/crypto/crypto.h b/src/crypto/crypto.h
index 7ddc0150f..599ae4f91 100644
--- a/src/crypto/crypto.h
+++ b/src/crypto/crypto.h
@@ -64,6 +64,11 @@ namespace crypto {
friend class crypto_ops;
};
+ POD_CLASS public_key_memsafe : epee::mlocked<tools::scrubbed<public_key>> {
+ public_key_memsafe() = default;
+ public_key_memsafe(const public_key &original) { memcpy(this->data, original.data, 32); }
+ };
+
using secret_key = epee::mlocked<tools::scrubbed<ec_scalar>>;
POD_CLASS public_keyV {
@@ -100,7 +105,7 @@ namespace crypto {
void random32_unbiased(unsigned char *bytes);
static_assert(sizeof(ec_point) == 32 && sizeof(ec_scalar) == 32 &&
- sizeof(public_key) == 32 && sizeof(secret_key) == 32 &&
+ sizeof(public_key) == 32 && sizeof(public_key_memsafe) == 32 && sizeof(secret_key) == 32 &&
sizeof(key_derivation) == 32 && sizeof(key_image) == 32 &&
sizeof(signature) == 64, "Invalid structure size");
@@ -310,9 +315,13 @@ namespace crypto {
const extern crypto::public_key null_pkey;
const extern crypto::secret_key null_skey;
+
+ inline bool operator<(const public_key &p1, const public_key &p2) { return memcmp(&p1, &p2, sizeof(public_key)) < 0; }
+ inline bool operator>(const public_key &p1, const public_key &p2) { return p2 < p1; }
}
CRYPTO_MAKE_HASHABLE(public_key)
CRYPTO_MAKE_HASHABLE_CONSTANT_TIME(secret_key)
+CRYPTO_MAKE_HASHABLE_CONSTANT_TIME(public_key_memsafe)
CRYPTO_MAKE_HASHABLE(key_image)
CRYPTO_MAKE_COMPARABLE(signature)
diff --git a/src/crypto/rx-slow-hash.c b/src/crypto/rx-slow-hash.c
index 801987e37..247c9032f 100644
--- a/src/crypto/rx-slow-hash.c
+++ b/src/crypto/rx-slow-hash.c
@@ -63,6 +63,7 @@ static rx_state rx_s[2] = {{CTHR_MUTEX_INIT,{0},0,0},{CTHR_MUTEX_INIT,{0},0,0}};
static randomx_dataset *rx_dataset;
static int rx_dataset_nomem;
+static int rx_dataset_nolp;
static uint64_t rx_dataset_height;
static THREADV randomx_vm *rx_vm = NULL;
@@ -316,10 +317,11 @@ void rx_slow_hash(const uint64_t mainheight, const uint64_t seedheight, const ch
}
CTHR_MUTEX_UNLOCK(rx_dataset_mutex);
}
- if (!(disabled_flags() & RANDOMX_FLAG_LARGE_PAGES)) {
+ if (!(disabled_flags() & RANDOMX_FLAG_LARGE_PAGES) && !rx_dataset_nolp) {
rx_vm = randomx_create_vm(flags | RANDOMX_FLAG_LARGE_PAGES, rx_sp->rs_cache, rx_dataset);
if(rx_vm == NULL) { //large pages failed
mdebug(RX_LOGCAT, "Couldn't use largePages for RandomX VM");
+ rx_dataset_nolp = 1;
}
}
if (rx_vm == NULL)
@@ -370,5 +372,6 @@ void rx_stop_mining(void) {
randomx_release_dataset(rd);
}
rx_dataset_nomem = 0;
+ rx_dataset_nolp = 0;
CTHR_MUTEX_UNLOCK(rx_dataset_mutex);
}