diff options
Diffstat (limited to 'libotr/libgcrypt-1.8.7/tests/mpitests.c')
-rw-r--r-- | libotr/libgcrypt-1.8.7/tests/mpitests.c | 580 |
1 files changed, 580 insertions, 0 deletions
diff --git a/libotr/libgcrypt-1.8.7/tests/mpitests.c b/libotr/libgcrypt-1.8.7/tests/mpitests.c new file mode 100644 index 0000000..18156d1 --- /dev/null +++ b/libotr/libgcrypt-1.8.7/tests/mpitests.c @@ -0,0 +1,580 @@ +/* mpitests.c - basic mpi tests + * Copyright (C) 2001, 2002, 2003, 2006 Free Software Foundation, Inc. + * Copyright (C) 2013 g10 Code GmbH + * + * This file is part of Libgcrypt. + * + * Libgcrypt is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Libgcrypt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> + +#ifdef _GCRYPT_IN_LIBGCRYPT +# include "../src/gcrypt-int.h" +#else +# include <gcrypt.h> +#endif + +#define PGM "mpitests" +#include "t-common.h" + + +/* Set up some test patterns */ + +/* 48 bytes with value 1: this results in 8 limbs for 64bit limbs, 16limb for 32 bit limbs */ +unsigned char ones[] = { + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 +}; + +/* 48 bytes with value 2: this results in 8 limbs for 64bit limbs, 16limb for 32 bit limbs */ +unsigned char twos[] = { + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02 +}; + +/* 48 bytes with value 3: this results in 8 limbs for 64bit limbs, 16limb for 32 bit limbs */ +unsigned char threes[] = { + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 +}; + +/* 48 bytes with value 0x80: this results in 8 limbs for 64bit limbs, 16limb for 32 bit limbs */ +unsigned char eighties[] = { + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 +}; + +/* 48 bytes with value 0xff: this results in 8 limbs for 64bit limbs, 16limb for 32 bit limbs */ +unsigned char manyff[] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff +}; + + +static int +test_const_and_immutable (void) +{ + gcry_mpi_t one, second_one; + + one = gcry_mpi_set_ui (NULL, 1); + if (gcry_mpi_get_flag (one, GCRYMPI_FLAG_IMMUTABLE) + || gcry_mpi_get_flag (one, GCRYMPI_FLAG_CONST)) + die ("immutable or const flag initially set\n"); + + second_one = gcry_mpi_copy (one); + if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_IMMUTABLE)) + die ("immutable flag set after copy\n"); + if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_CONST)) + die ("const flag set after copy\n"); + gcry_mpi_release (second_one); + + gcry_mpi_set_flag (one, GCRYMPI_FLAG_IMMUTABLE); + if (!gcry_mpi_get_flag (one, GCRYMPI_FLAG_IMMUTABLE)) + die ("failed to set immutable flag\n"); + if (gcry_mpi_get_flag (one, GCRYMPI_FLAG_CONST)) + die ("const flag unexpectly set\n"); + + second_one = gcry_mpi_copy (one); + if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_IMMUTABLE)) + die ("immutable flag not cleared after copy\n"); + if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_CONST)) + die ("const flag unexpectly set after copy\n"); + gcry_mpi_release (second_one); + + gcry_mpi_clear_flag (one, GCRYMPI_FLAG_IMMUTABLE); + if (gcry_mpi_get_flag (one, GCRYMPI_FLAG_IMMUTABLE)) + die ("failed to clear immutable flag\n"); + if (gcry_mpi_get_flag (one, GCRYMPI_FLAG_CONST)) + die ("const flag unexpectly set\n"); + + gcry_mpi_set_flag (one, GCRYMPI_FLAG_CONST); + if (!gcry_mpi_get_flag (one, GCRYMPI_FLAG_CONST)) + die ("failed to set const flag\n"); + if (!gcry_mpi_get_flag (one, GCRYMPI_FLAG_IMMUTABLE)) + die ("failed to set immutable flag with const flag\n"); + + second_one = gcry_mpi_copy (one); + if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_IMMUTABLE)) + die ("immutable flag not cleared after copy\n"); + if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_CONST)) + die ("const flag not cleared after copy\n"); + gcry_mpi_release (second_one); + + gcry_mpi_clear_flag (one, GCRYMPI_FLAG_IMMUTABLE); + if (!gcry_mpi_get_flag (one, GCRYMPI_FLAG_IMMUTABLE)) + die ("clearing immutable flag not ignored for a constant MPI\n"); + if (!gcry_mpi_get_flag (one, GCRYMPI_FLAG_CONST)) + die ("const flag unexpectly cleared\n"); + + + second_one = gcry_mpi_set (NULL, GCRYMPI_CONST_ONE); + if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_IMMUTABLE)) + die ("immutable flag not cleared by mpi_set (NULL,x)\n"); + if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_CONST)) + die ("const flag not cleared by mpi_set (NULL,x)\n"); + gcry_mpi_release (second_one); + + second_one = gcry_mpi_set_ui (NULL, 42); + gcry_mpi_set (second_one, GCRYMPI_CONST_ONE); + if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_IMMUTABLE)) + die ("immutable flag not cleared after mpi_set (a,x)\n"); + if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_CONST)) + die ("const flag not cleared mpi_set (a,x)\n"); + gcry_mpi_release (second_one); + + + /* Due to the the constant flag the release below should be a NOP + and will leak memory. */ + gcry_mpi_release (one); + return 1; +} + + +static void +test_opaque (void) +{ + gcry_mpi_t a; + char *p; + unsigned int nbits; + + p = gcry_xstrdup ("This is a test buffer"); + a = gcry_mpi_set_opaque (NULL, p, 21*8+1); /* (a non byte aligned length) */ + + if (!gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE)) + die ("opaque flag not set\n"); + + p = gcry_mpi_get_opaque (a, &nbits); + if (!p) + die ("gcry_mpi_get_opaque returned NULL\n"); + if (nbits != 21*8+1) + die ("gcry_mpi_get_opaque returned a changed bit size\n"); + if (strcmp (p, "This is a test buffer")) + die ("gcry_mpi_get_opaque returned a changed buffer\n"); + + if (debug) + gcry_log_debugmpi ("mpi", a); + gcry_mpi_release (a); + + p = gcry_xstrdup ("This is a test buffer"); + a = gcry_mpi_set_opaque_copy (NULL, p, 21*8+1); + gcry_free (p); + + if (!gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE)) + die ("opaque flag not set\n"); + + p = gcry_mpi_get_opaque (a, &nbits); + if (!p) + die ("gcry_mpi_get_opaque returned NULL\n"); + if (nbits != 21*8+1) + die ("gcry_mpi_get_opaque returned a changed bit size\n"); + if (strcmp (p, "This is a test buffer")) + die ("gcry_mpi_get_opaque returned a changed buffer\n"); + + if (debug) + gcry_log_debugmpi ("mpi", a); + + gcry_mpi_release (a); +} + + +static void +test_maxsize (void) +{ + gpg_error_t err; + gcry_mpi_t a; + char buffer[2+2048]; /* For PGP: 2 length bytes and 16384 bits. */ + + memset (buffer, 0x55, sizeof buffer); + + /* We use a short buffer but a give a too large length to simulate a + * programming error. In case this test fails (i.e. die() is + * called) the scan function may have access data outside of BUFFER + * which may result in a segv but we ignore that to avoid actually + * allocating such a long buffer. */ + err = gcry_mpi_scan (&a, GCRYMPI_FMT_USG, buffer, 16*1024*1024 +1, NULL); + if (gpg_err_code (err) != GPG_ERR_INV_OBJ) + die ("gcry_mpi_scan does not detect its generic input limit\n"); + + /* Now test the PGP limit. The scan code check the two length bytes + * from the buffer and thus it is sufficient to fake them. */ + buffer[0] = (16385 >> 8); + buffer[1] = (16385 & 0xff); + err = gcry_mpi_scan (&a, GCRYMPI_FMT_PGP, buffer, sizeof buffer, NULL); + if (gpg_err_code (err) != GPG_ERR_INV_OBJ) + die ("gcry_mpi_scan does not detect the PGP input limit\n"); + + buffer[0] = (16384 >> 8); + buffer[1] = (16384 & 0xff); + + err = gcry_mpi_scan (&a, GCRYMPI_FMT_PGP, buffer, sizeof buffer, NULL); + if (err) + die ("gcry_mpi_scan did not parse a large PGP: %s\n", gpg_strerror (err)); + gcry_mpi_release (a); +} + + +static void +test_cmp (void) +{ + gpg_error_t rc; + gcry_mpi_t zero, zero2; + gcry_mpi_t one; + gcry_mpi_t two; + gcry_mpi_t all_ones; + gcry_mpi_t opa1, opa2; + gcry_mpi_t opa1s, opa2s; + gcry_mpi_t opa0, opa02; + + zero = gcry_mpi_new (0); + zero2= gcry_mpi_set_ui (NULL, 0); + one = gcry_mpi_set_ui (NULL, 1); + two = gcry_mpi_set_ui (NULL, 2); + rc = gcry_mpi_scan (&all_ones, GCRYMPI_FMT_USG, ones, sizeof(ones), NULL); + if (rc) + die ("scanning number failed at line %d", __LINE__); + opa0 = gcry_mpi_set_opaque (NULL, gcry_xstrdup ("a"), 0); + opa02 = gcry_mpi_set_opaque (NULL, gcry_xstrdup ("b"), 0); + opa1 = gcry_mpi_set_opaque (NULL, gcry_xstrdup ("aaaaaaaaaaaaaaaa"), 16*8); + opa1s = gcry_mpi_set_opaque (NULL, gcry_xstrdup ("a"), 1*8); + opa2 = gcry_mpi_set_opaque (NULL, gcry_xstrdup ("bbbbbbbbbbbbbbbb"), 16*8); + opa2s = gcry_mpi_set_opaque (NULL, gcry_xstrdup ("b"), 1*8); + + + /* Single limb test with cmp_ui */ + if (gcry_mpi_cmp_ui (zero, 0)) + fail ("mpi_cmp_ui failed at line %d", __LINE__); + if (!(gcry_mpi_cmp_ui (zero, 1) < 0)) + fail ("mpi_cmp_ui failed at line %d", __LINE__); + if (!(gcry_mpi_cmp_ui (zero, (-1)) < 0)) + fail ("mpi_cmp_ui failed at line %d", __LINE__); + + if (gcry_mpi_cmp_ui (two, 2)) + fail ("mpi_cmp_ui failed at line %d", __LINE__); + if (!(gcry_mpi_cmp_ui (two, 3) < 0)) + fail ("mpi_cmp_ui failed at line %d", __LINE__); + if (!(gcry_mpi_cmp_ui (two, 1) > 0)) + fail ("mpi_cmp_ui failed at line %d", __LINE__); + + /* Multi limb tests with cmp_ui. */ + if (!(gcry_mpi_cmp_ui (all_ones, 0) > 0)) + fail ("mpi_cmp_ui failed at line %d", __LINE__); + if (!(gcry_mpi_cmp_ui (all_ones, (-1)) > 0)) + fail ("mpi_cmp_ui failed at line %d", __LINE__); + + /* Single limb test with cmp */ + if (gcry_mpi_cmp (zero, zero2)) + fail ("mpi_cmp failed at line %d", __LINE__); + if (!(gcry_mpi_cmp (zero, one) < 0)) + fail ("mpi_cmp failed at line %d", __LINE__); + if (!(gcry_mpi_cmp (one, zero) > 0)) + fail ("mpi_cmp failed at line %d", __LINE__); + + gcry_mpi_neg (one, one); + if (!(gcry_mpi_cmp (zero, one) > 0)) + fail ("mpi_cmp failed at line %d", __LINE__); + if (!(gcry_mpi_cmp (one, zero) < 0)) + fail ("mpi_cmp failed at line %d", __LINE__); + if (!(gcry_mpi_cmp (one, two) < 0)) + fail ("mpi_cmp failed at line %d", __LINE__); + gcry_mpi_neg (one, one); + + if (!(gcry_mpi_cmp (one, two) < 0)) + fail ("mpi_cmp failed at line %d", __LINE__); + if (!(gcry_mpi_cmp (two, one) > 0)) + fail ("mpi_cmp failed at line %d", __LINE__); + if (!(gcry_mpi_cmp (one, all_ones) < 0)) + fail ("mpi_cmp failed at line %d", __LINE__); + + /* Tests with opaque values. */ + if (!(gcry_mpi_cmp (opa1, one) < 0)) + fail ("mpi_cmp failed at line %d", __LINE__); + if (!(gcry_mpi_cmp (one, opa1) > 0)) + fail ("mpi_cmp failed at line %d", __LINE__); + if (!(gcry_mpi_cmp (opa0, opa02) == 0)) + fail ("mpi_cmp failed at line %d", __LINE__); + if (!(gcry_mpi_cmp (opa1s, opa1) < 0)) + fail ("mpi_cmp failed at line %d", __LINE__); + if (!(gcry_mpi_cmp (opa2, opa1s) > 0)) + fail ("mpi_cmp failed at line %d", __LINE__); + if (!(gcry_mpi_cmp (opa1, opa2) < 0)) + fail ("mpi_cmp failed at line %d", __LINE__); + if (!(gcry_mpi_cmp (opa2, opa1) > 0)) + fail ("mpi_cmp failed at line %d", __LINE__); + if (!(gcry_mpi_cmp (opa1, opa1) == 0)) + fail ("mpi_cmp failed at line %d", __LINE__); + + + gcry_mpi_release(opa2s); + gcry_mpi_release(opa2); + gcry_mpi_release(opa1s); + gcry_mpi_release(opa1); + gcry_mpi_release(opa02); + gcry_mpi_release(opa0); + gcry_mpi_release(all_ones); + gcry_mpi_release(two); + gcry_mpi_release(one); + gcry_mpi_release(zero2); + gcry_mpi_release(zero); +} + + +static int +test_add (void) +{ + gcry_mpi_t one; + gcry_mpi_t two; + gcry_mpi_t ff; + gcry_mpi_t result; + unsigned char* pc; + + gcry_mpi_scan(&one, GCRYMPI_FMT_USG, ones, sizeof(ones), NULL); + gcry_mpi_scan(&two, GCRYMPI_FMT_USG, twos, sizeof(twos), NULL); + gcry_mpi_scan(&ff, GCRYMPI_FMT_USG, manyff, sizeof(manyff), NULL); + result = gcry_mpi_new(0); + + gcry_mpi_add(result, one, two); + gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result); + if (debug) + gcry_log_debug ("Result of one plus two:\n%s\n", pc); + gcry_free(pc); + + gcry_mpi_add(result, ff, one); + gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result); + if (debug) + gcry_log_debug ("Result of ff plus one:\n%s\n", pc); + gcry_free(pc); + + gcry_mpi_release(one); + gcry_mpi_release(two); + gcry_mpi_release(ff); + gcry_mpi_release(result); + return 1; +} + + +static int +test_sub (void) +{ + gcry_mpi_t one; + gcry_mpi_t two; + gcry_mpi_t result; + unsigned char* pc; + + gcry_mpi_scan(&one, GCRYMPI_FMT_USG, ones, sizeof(ones), NULL); + gcry_mpi_scan(&two, GCRYMPI_FMT_USG, twos, sizeof(twos), NULL); + result = gcry_mpi_new(0); + gcry_mpi_sub(result, two, one); + + gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result); + if (debug) + gcry_log_debug ("Result of two minus one:\n%s\n", pc); + gcry_free(pc); + + gcry_mpi_release(one); + gcry_mpi_release(two); + gcry_mpi_release(result); + return 1; +} + + +static int +test_mul (void) +{ + gcry_mpi_t two; + gcry_mpi_t three; + gcry_mpi_t result; + unsigned char* pc; + + gcry_mpi_scan(&two, GCRYMPI_FMT_USG, twos, sizeof(twos), NULL); + gcry_mpi_scan(&three, GCRYMPI_FMT_USG, threes, sizeof(threes), NULL); + result = gcry_mpi_new(0); + gcry_mpi_mul(result, two, three); + + gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result); + if (debug) + gcry_log_debug ("Result of two mul three:\n%s\n", pc); + gcry_free(pc); + + gcry_mpi_release(two); + gcry_mpi_release(three); + gcry_mpi_release(result); + return 1; +} + + +/* What we test here is that we don't overwrite our args and that + using the same mpi for several args works. */ +static int +test_powm (void) +{ + int b_int = 17; + int e_int = 3; + int m_int = 19; + gcry_mpi_t base = gcry_mpi_set_ui (NULL, b_int); + gcry_mpi_t exp = gcry_mpi_set_ui (NULL, e_int); + gcry_mpi_t mod = gcry_mpi_set_ui (NULL, m_int); + gcry_mpi_t res = gcry_mpi_new (0); + + gcry_mpi_powm (res, base, exp, mod); + if (gcry_mpi_cmp_ui (base, b_int)) + die ("test_powm failed for base at %d\n", __LINE__); + if (gcry_mpi_cmp_ui (exp, e_int)) + die ("test_powm_ui failed for exp at %d\n", __LINE__); + if (gcry_mpi_cmp_ui (mod, m_int)) + die ("test_powm failed for mod at %d\n", __LINE__); + + /* Check using base for the result. */ + gcry_mpi_set_ui (base, b_int); + gcry_mpi_set_ui (exp, e_int); + gcry_mpi_set_ui(mod, m_int); + gcry_mpi_powm (base, base, exp, mod); + if (gcry_mpi_cmp (res, base)) + die ("test_powm failed at %d\n", __LINE__); + if (gcry_mpi_cmp_ui (exp, e_int)) + die ("test_powm_ui failed for exp at %d\n", __LINE__); + if (gcry_mpi_cmp_ui (mod, m_int)) + die ("test_powm failed for mod at %d\n", __LINE__); + + /* Check using exp for the result. */ + gcry_mpi_set_ui (base, b_int); + gcry_mpi_set_ui (exp, e_int); + gcry_mpi_set_ui(mod, m_int); + gcry_mpi_powm (exp, base, exp, mod); + if (gcry_mpi_cmp (res, exp)) + die ("test_powm failed at %d\n", __LINE__); + if (gcry_mpi_cmp_ui (base, b_int)) + die ("test_powm failed for base at %d\n", __LINE__); + if (gcry_mpi_cmp_ui (mod, m_int)) + die ("test_powm failed for mod at %d\n", __LINE__); + + /* Check using mod for the result. */ + gcry_mpi_set_ui (base, b_int); + gcry_mpi_set_ui (exp, e_int); + gcry_mpi_set_ui(mod, m_int); + gcry_mpi_powm (mod, base, exp, mod); + if (gcry_mpi_cmp (res, mod)) + die ("test_powm failed at %d\n", __LINE__); + if (gcry_mpi_cmp_ui (base, b_int)) + die ("test_powm failed for base at %d\n", __LINE__); + if (gcry_mpi_cmp_ui (exp, e_int)) + die ("test_powm_ui failed for exp at %d\n", __LINE__); + + /* Now check base ^ base mod mod. */ + gcry_mpi_set_ui (base, b_int); + gcry_mpi_set_ui(mod, m_int); + gcry_mpi_powm (res, base, base, mod); + if (gcry_mpi_cmp_ui (base, b_int)) + die ("test_powm failed for base at %d\n", __LINE__); + if (gcry_mpi_cmp_ui (mod, m_int)) + die ("test_powm failed for mod at %d\n", __LINE__); + + /* Check base ^ base mod mod with base as result. */ + gcry_mpi_set_ui (base, b_int); + gcry_mpi_set_ui(mod, m_int); + gcry_mpi_powm (base, base, base, mod); + if (gcry_mpi_cmp (res, base)) + die ("test_powm failed at %d\n", __LINE__); + if (gcry_mpi_cmp_ui (mod, m_int)) + die ("test_powm failed for mod at %d\n", __LINE__); + + /* Check base ^ base mod mod with mod as result. */ + gcry_mpi_set_ui (base, b_int); + gcry_mpi_set_ui(mod, m_int); + gcry_mpi_powm (mod, base, base, mod); + if (gcry_mpi_cmp (res, mod)) + die ("test_powm failed at %d\n", __LINE__); + if (gcry_mpi_cmp_ui (base, b_int)) + die ("test_powm failed for base at %d\n", __LINE__); + + /* Now check base ^ base mod base. */ + gcry_mpi_set_ui (base, b_int); + gcry_mpi_powm (res, base, base, base); + if (gcry_mpi_cmp_ui (base, b_int)) + die ("test_powm failed for base at %d\n", __LINE__); + + /* Check base ^ base mod base with base as result. */ + gcry_mpi_set_ui (base, b_int); + gcry_mpi_powm (base, base, base, base); + if (gcry_mpi_cmp (res, base)) + die ("test_powm failed at %d\n", __LINE__); + + /* Check for a case: base is negative and expo is even. */ + gcry_mpi_set_ui (base, b_int); + gcry_mpi_neg (base, base); + gcry_mpi_set_ui (exp, e_int * 2); + gcry_mpi_set_ui(mod, m_int); + gcry_mpi_powm (res, base, exp, mod); + /* Result should be positive and it's 7 = (-17)^6 mod 19. */ + if (gcry_mpi_is_neg (res) || gcry_mpi_cmp_ui (res, 7)) + { + if (verbose) + { + fprintf (stderr, "is_neg: %d\n", gcry_mpi_is_neg (res)); + fprintf (stderr, "mpi: "); + gcry_mpi_dump (res); + putc ('\n', stderr); + } + die ("test_powm failed for negative base at %d\n", __LINE__); + } + + gcry_mpi_release (base); + gcry_mpi_release (exp); + gcry_mpi_release (mod); + gcry_mpi_release (res); + /* Fixme: We should add the rest of the cases of course. */ + + + + return 1; +} + + +int +main (int argc, char* argv[]) +{ + if (argc > 1 && !strcmp (argv[1], "--verbose")) + verbose = 1; + else if (argc > 1 && !strcmp (argv[1], "--debug")) + verbose = debug = 1; + + if (!gcry_check_version (GCRYPT_VERSION)) + { + fputs ("version mismatch\n", stderr); + exit (1); + } + xgcry_control(GCRYCTL_DISABLE_SECMEM); + + test_const_and_immutable (); + test_opaque (); + test_maxsize (); + test_cmp (); + test_add (); + test_sub (); + test_mul (); + test_powm (); + + return !!error_count; +} |