From 137e77afb4d93c2010d4f307603f4326aaff4944 Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Tue, 4 Nov 2014 12:41:42 +0700 Subject: [PATCH] Address 'constant-time' TODOs in field impls --- src/field_10x26_impl.h | 12 ++++++------ src/field_5x52_impl.h | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/field_10x26_impl.h b/src/field_10x26_impl.h index 2172222..5a9df33 100644 --- a/src/field_10x26_impl.h +++ b/src/field_10x26_impl.h @@ -110,13 +110,13 @@ void static inline secp256k1_fe_set_int(secp256k1_fe_t *r, int a) { #endif } -// TODO: not constant time! int static inline secp256k1_fe_is_zero(const secp256k1_fe_t *a) { #ifdef VERIFY VERIFY_CHECK(a->normalized); secp256k1_fe_verify(a); #endif - return (a->n[0] == 0 && a->n[1] == 0 && a->n[2] == 0 && a->n[3] == 0 && a->n[4] == 0 && a->n[5] == 0 && a->n[6] == 0 && a->n[7] == 0 && a->n[8] == 0 && a->n[9] == 0); + const uint32_t *t = a->n; + return (t[0] | t[1] | t[2] | t[3] | t[4] | t[5] | t[6] | t[7] | t[8] | t[9]) == 0; } int static inline secp256k1_fe_is_odd(const secp256k1_fe_t *a) { @@ -137,7 +137,6 @@ void static inline secp256k1_fe_clear(secp256k1_fe_t *a) { } } -// TODO: not constant time! int static inline secp256k1_fe_equal(const secp256k1_fe_t *a, const secp256k1_fe_t *b) { #ifdef VERIFY VERIFY_CHECK(a->normalized); @@ -145,8 +144,9 @@ int static inline secp256k1_fe_equal(const secp256k1_fe_t *a, const secp256k1_fe secp256k1_fe_verify(a); secp256k1_fe_verify(b); #endif - return (a->n[0] == b->n[0] && a->n[1] == b->n[1] && a->n[2] == b->n[2] && a->n[3] == b->n[3] && a->n[4] == b->n[4] && - a->n[5] == b->n[5] && a->n[6] == b->n[6] && a->n[7] == b->n[7] && a->n[8] == b->n[8] && a->n[9] == b->n[9]); + const uint32_t *t = a->n, *u = b->n; + return ((t[0]^u[0]) | (t[1]^u[1]) | (t[2]^u[2]) | (t[3]^u[3]) | (t[4]^u[4]) + | (t[5]^u[5]) | (t[6]^u[6]) | (t[7]^u[7]) | (t[8]^u[8]) | (t[9]^u[9])) == 0; } void static secp256k1_fe_set_b32(secp256k1_fe_t *r, const unsigned char *a) { @@ -166,7 +166,7 @@ void static secp256k1_fe_set_b32(secp256k1_fe_t *r, const unsigned char *a) { #endif } -/** Convert a field element to a 32-byte big endian value. Requires the input to be normalized */ +/** Convert a field element to a 32-bote big endian value. Requires the input to be normalized */ void static secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe_t *a) { #ifdef VERIFY VERIFY_CHECK(a->normalized); diff --git a/src/field_5x52_impl.h b/src/field_5x52_impl.h index dce16d4..5afabae 100644 --- a/src/field_5x52_impl.h +++ b/src/field_5x52_impl.h @@ -109,13 +109,13 @@ void static inline secp256k1_fe_set_int(secp256k1_fe_t *r, int a) { #endif } -// TODO: not constant time! int static inline secp256k1_fe_is_zero(const secp256k1_fe_t *a) { #ifdef VERIFY VERIFY_CHECK(a->normalized); secp256k1_fe_verify(a); #endif - return (a->n[0] == 0 && a->n[1] == 0 && a->n[2] == 0 && a->n[3] == 0 && a->n[4] == 0); + const uint64_t *t = a->n; + return (t[0] | t[1] | t[2] | t[3] | t[4]) == 0; } int static inline secp256k1_fe_is_odd(const secp256k1_fe_t *a) { @@ -136,7 +136,6 @@ void static inline secp256k1_fe_clear(secp256k1_fe_t *a) { } } -// TODO: not constant time! int static inline secp256k1_fe_equal(const secp256k1_fe_t *a, const secp256k1_fe_t *b) { #ifdef VERIFY VERIFY_CHECK(a->normalized); @@ -144,7 +143,8 @@ int static inline secp256k1_fe_equal(const secp256k1_fe_t *a, const secp256k1_fe secp256k1_fe_verify(a); secp256k1_fe_verify(b); #endif - return (a->n[0] == b->n[0] && a->n[1] == b->n[1] && a->n[2] == b->n[2] && a->n[3] == b->n[3] && a->n[4] == b->n[4]); + const uint64_t *t = a->n, *u = b->n; + return ((t[0]^u[0]) | (t[1]^u[1]) | (t[2]^u[2]) | (t[3]^u[3]) | (t[4]^u[4])) == 0; } void static secp256k1_fe_set_b32(secp256k1_fe_t *r, const unsigned char *a) {