Ensure that x**0 mod 1 = 0.
authorAdam Langley <agl@chromium.org>
Tue, 23 Apr 2013 16:13:51 +0000 (12:13 -0400)
committerEmilia Kasper <emilia@openssl.org>
Thu, 4 Sep 2014 14:06:51 +0000 (16:06 +0200)
(cherry picked from commit 2b0180c37fa6ffc48ee40caa831ca398b828e680)

Reviewed-by: Ben Laurie <ben@openssl.org>
crypto/bn/bn_exp.c
crypto/bn/exptest.c

index 5e7eb3373ffd170ef7d826d497bc42d69f9b5d31..611fa3262bed9171d244e4e32e00dae9d3d02e14 100644 (file)
@@ -874,7 +874,14 @@ int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p,
        bits = BN_num_bits(p);
        if (bits == 0)
                {
-               ret = BN_one(rr);
+               /* x**0 mod 1 is still zero. */
+               if (BN_is_one(m))
+                       {
+                       ret = 1;
+                       BN_zero(rr);
+                       }
+               else
+                       ret = BN_one(rr);
                return ret;
                }
        if (a == 0)
index 074a8e882a8eb53f941cc2b0a493ee22e0e18730..5fa02a1229e88c54d4f29c14eef2f166059b52da 100644 (file)
 
 static const char rnd_seed[] = "string to make the random number generator think it has entropy";
 
+/* test_exp_mod_zero tests that x**0 mod 1 == 0. It returns zero on success. */
+static int test_exp_mod_zero() {
+       BIGNUM a, p, m;
+       BIGNUM r;
+       BN_CTX *ctx = BN_CTX_new();
+       int ret = 1;
+
+       BN_init(&m);
+       BN_one(&m);
+
+       BN_init(&a);
+       BN_one(&a);
+
+       BN_init(&p);
+       BN_zero(&p);
+
+       BN_init(&r);
+       BN_mod_exp(&r, &a, &p, &m, ctx);
+       BN_CTX_free(ctx);
+
+       if (BN_is_zero(&r))
+               ret = 0;
+       else
+               {
+               printf("1**0 mod 1 = ");
+               BN_print_fp(stdout, &r);
+               printf(", should be 0\n");
+               }
+
+       BN_free(&r);
+       BN_free(&a);
+       BN_free(&p);
+       BN_free(&m);
+
+       return ret;
+}
+
 int main(int argc, char *argv[])
        {
        BN_CTX *ctx;
@@ -190,7 +227,13 @@ int main(int argc, char *argv[])
        ERR_remove_thread_state(NULL);
        CRYPTO_mem_leaks(out);
        BIO_free(out);
-       printf(" done\n");
+       printf("\n");
+
+       if (test_exp_mod_zero() != 0)
+               goto err;
+
+       printf("done\n");
+
        EXIT(0);
 err:
        ERR_load_crypto_strings();