/**************** * Note: This copy function should not interpret the MPI * but copy it transparently. */ gcry_mpi_t gcry_mpi_copy( gcry_mpi_t a ) { int i; gcry_mpi_t b; if( a && (a->flags & 4) ) { void *p = gcry_is_secure(a->d)? gcry_xmalloc_secure( (a->sign+7)/8 ) : gcry_xmalloc( (a->sign+7)/8 ); memcpy( p, a->d, (a->sign+7)/8 ); b = gcry_mpi_set_opaque( NULL, p, a->sign ); } else if( a ) { b = mpi_is_secure(a)? mpi_alloc_secure( a->nlimbs ) : mpi_alloc( a->nlimbs ); b->nlimbs = a->nlimbs; b->sign = a->sign; b->flags = a->flags; for(i=0; i < b->nlimbs; i++ ) b->d[i] = a->d[i]; } else b = NULL; return b; }
static gcry_mpi_t hex2mpiopa (const char *string) { char *buffer; size_t buflen; gcry_mpi_t val; buffer = hex2buffer (string, &buflen); if (!buffer) die ("hex2mpiopa '%s' failed: parser error\n", string); val = gcry_mpi_set_opaque (NULL, buffer, buflen*8); if (!buffer) die ("hex2mpiopa '%s' failed: set_opaque error\n", string); return val; }
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); }
/**************** * This function allocates an MPI which is optimized to hold * a value as large as the one given in the argument and allocates it * with the same flags as A. */ gcry_mpi_t _gcry_mpi_alloc_like( gcry_mpi_t a ) { gcry_mpi_t b; if( a && (a->flags & 4) ) { int n = (a->sign+7)/8; void *p = gcry_is_secure(a->d)? gcry_malloc_secure( n ) : gcry_malloc( n ); memcpy( p, a->d, n ); b = gcry_mpi_set_opaque( NULL, p, a->sign ); } else if( a ) { b = mpi_is_secure(a)? mpi_alloc_secure( a->nlimbs ) : mpi_alloc( a->nlimbs ); b->nlimbs = 0; b->sign = 0; b->flags = a->flags; } else b = NULL; return b; }
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); }