From b36a3156b6cc76294267d7083ddd31e6e5f9c170 Mon Sep 17 00:00:00 2001 From: Adam Langley Date: Fri, 20 Jun 2014 12:00:00 -0700 Subject: [PATCH] Add another bn modexp test. Add a test based on multiplication optimizations from OpenSSL HEAD (1.1.0-dev) Based on openssl-SNAP-20111003 --- crypto/bn/bn.h | 3 -- crypto/bn/bn_test.c | 74 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 73 insertions(+), 4 deletions(-) diff --git a/crypto/bn/bn.h b/crypto/bn/bn.h index 16ce65f8..79b918a4 100644 --- a/crypto/bn/bn.h +++ b/crypto/bn/bn.h @@ -709,9 +709,6 @@ int BN_mod_exp_mont_word(BIGNUM *r, BN_ULONG a, const BIGNUM *p, int BN_mod_exp2_mont(BIGNUM *r, const BIGNUM *a1, const BIGNUM *p1, const BIGNUM *a2, const BIGNUM *p2, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); -int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx); - /* Private functions */ diff --git a/crypto/bn/bn_test.c b/crypto/bn/bn_test.c index 1a898021..c29aec8a 100644 --- a/crypto/bn/bn_test.c +++ b/crypto/bn/bn_test.c @@ -98,6 +98,7 @@ int test_mod_exp(BIO *bp, BN_CTX *ctx); int test_mod_exp_mont_consttime(BIO *bp, BN_CTX *ctx); int test_exp(BIO *bp, BN_CTX *ctx); int test_mod_sqrt(BIO *bp, BN_CTX *ctx); +int test_mod_exp_mont5(BIO *bp, BN_CTX *ctx); #if 0 int test_gf2m_add(BIO *bp); int test_gf2m_mod(BIO *bp); @@ -243,8 +244,10 @@ int main(int argc, char *argv[]) { (void)BIO_flush(out); message(out, "BN_mod_exp_mont_consttime"); - if (!test_mod_exp_mont_consttime(out, ctx)) + if (!test_mod_exp_mont_consttime(out, ctx) || + !test_mod_exp_mont5(out, ctx)) { goto err; + } (void)BIO_flush(out); message(out, "BN_exp"); @@ -1000,6 +1003,75 @@ int test_mod_exp_mont_consttime(BIO *bp, BN_CTX *ctx) { return (1); } +/* Test constant-time modular exponentiation with 1024-bit inputs, + * which on x86_64 cause a different code branch to be taken. */ +int test_mod_exp_mont5(BIO *bp, BN_CTX *ctx) { + BIGNUM *a, *p, *m, *d, *e; + + BN_MONT_CTX *mont; + + a = BN_new(); + p = BN_new(); + m = BN_new(); + d = BN_new(); + e = BN_new(); + + mont = BN_MONT_CTX_new(); + + BN_rand(m, 1024, 0, 1); /* must be odd for montgomery */ + /* Zero exponent */ + BN_rand(a, 1024, 0, 0); + BN_zero(p); + if (!BN_mod_exp_mont_consttime(d, a, p, m, ctx, NULL)) + return 0; + if (!BN_is_one(d)) { + fprintf(stderr, "Modular exponentiation test failed!\n"); + return 0; + } + /* Zero input */ + BN_rand(p, 1024, 0, 0); + BN_zero(a); + if (!BN_mod_exp_mont_consttime(d, a, p, m, ctx, NULL)) + return 0; + if (!BN_is_zero(d)) { + fprintf(stderr, "Modular exponentiation test failed!\n"); + return 0; + } + /* Craft an input whose Montgomery representation is 1, + * i.e., shorter than the modulus m, in order to test + * the const time precomputation scattering/gathering. + */ + BN_one(a); + BN_MONT_CTX_set(mont, m, ctx); + if (!BN_from_montgomery(e, a, mont, ctx) || + !BN_mod_exp_mont_consttime(d, e, p, m, ctx, NULL) || + !BN_mod_exp(a, e, p, m, ctx)) { + return 0; + } + if (BN_cmp(a, d) != 0) { + fprintf(stderr, "Modular exponentiation test failed!\n"); + return 0; + } + /* Finally, some regular test vectors. */ + BN_rand(e, 1024, 0, 0); + if (!BN_mod_exp_mont_consttime(d, e, p, m, ctx, NULL)) + return 0; + if (!BN_mod_exp(a, e, p, m, ctx)) + return 0; + if (BN_cmp(a, d) != 0) { + fprintf(stderr, "Modular exponentiation test failed!\n"); + return 0; + } + + BN_MONT_CTX_free(mont); + BN_free(a); + BN_free(p); + BN_free(m); + BN_free(d); + BN_free(e); + return (1); +} + int test_exp(BIO *bp, BN_CTX *ctx) { BIGNUM *a, *b, *d, *e, *one; int i;