diff options
author | Werner Koch <wk@gnupg.org> | 2013-03-13 15:08:33 +0100 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2013-03-13 15:08:33 +0100 |
commit | e005629bd7bebb3e13945645c6e1230b44ab16a2 (patch) | |
tree | 46dc8a478d794e103ee4e70ec5c0832902d1bcba /mpi | |
parent | 1fecae98ee7e0fa49b29f98efa6817ca121ed98a (diff) | |
download | libgcrypt-e005629bd7bebb3e13945645c6e1230b44ab16a2.tar.gz |
Add GCRYMPI_FLAG_CONST and make use constants.
* src/gcrypt.h.in (GCRYMPI_FLAG_CONST): New.
* src/mpi.h (mpi_is_const, mpi_const): New.
(enum gcry_mpi_constants, MPI_NUMBER_OF_CONSTANTS): New.
* mpi/mpiutil.c (_gcry_mpi_init): New.
(constants): New.
(_gcry_mpi_free): Do not release a constant flagged MPI.
(gcry_mpi_copy): Clear the const and immutable flags.
(gcry_mpi_set_flag, gcry_mpi_clear_flag, gcry_mpi_get_flag): Support
GCRYMPI_FLAG_CONST.
(_gcry_mpi_const): New.
* src/global.c (global_init): Call _gcry_mpi_init.
* mpi/ec.c (mpi_ec_ctx_s): Remove fields one, two, three, four, and
eight. Change all users to call mpi_const() instead.
* src/mpiutils.c (gcry_mpi_set_opaque): Check the immutable flag.
--
Allocating the trivial constants newly for every EC context is a waste
of memory and cpu cycles. We instead provide a simple mechanism to
internally support such constants. Using a new flag in THE API also
allows to mark an arbitrary MPI as constant. The drawback of the
constants is the their memory will never be deallocated. However,
that is what constants are about.
Diffstat (limited to 'mpi')
-rw-r--r-- | mpi/ec.c | 65 | ||||
-rw-r--r-- | mpi/mpiutil.c | 89 |
2 files changed, 99 insertions, 55 deletions
@@ -45,12 +45,6 @@ struct mpi_ec_ctx_s int a_is_pminus3; /* True if A = P - 3. */ - /* Some often used constants. */ - gcry_mpi_t one; - gcry_mpi_t two; - gcry_mpi_t three; - gcry_mpi_t four; - gcry_mpi_t eight; gcry_mpi_t two_inv_p; /* Scratch variables. */ @@ -374,15 +368,8 @@ ec_p_init (mpi_ec_t ctx, gcry_mpi_t p, gcry_mpi_t a) ctx->a_is_pminus3 = !mpi_cmp (ctx->a, tmp); mpi_free (tmp); - - /* Allocate constants. */ - ctx->one = mpi_alloc_set_ui (1); - ctx->two = mpi_alloc_set_ui (2); - ctx->three = mpi_alloc_set_ui (3); - ctx->four = mpi_alloc_set_ui (4); - ctx->eight = mpi_alloc_set_ui (8); ctx->two_inv_p = mpi_alloc (0); - ec_invm (ctx->two_inv_p, ctx->two, ctx); + ec_invm (ctx->two_inv_p, mpi_const (MPI_C_TWO), ctx); /* Allocate scratch variables. */ for (i=0; i< DIM(ctx->scratch); i++) @@ -417,12 +404,6 @@ ec_deinit (void *opaque) mpi_free (ctx->p); mpi_free (ctx->a); - mpi_free (ctx->one); - mpi_free (ctx->two); - mpi_free (ctx->three); - mpi_free (ctx->four); - mpi_free (ctx->eight); - mpi_free (ctx->two_inv_p); for (i=0; i< DIM(ctx->scratch); i++) @@ -563,9 +544,9 @@ _gcry_mpi_ec_dup_point (mpi_point_t result, mpi_point_t point, mpi_ec_t ctx) /* L1 = 3(X - Z^2)(X + Z^2) */ /* T1: used for Z^2. */ /* T2: used for the right term. */ - ec_powm (t1, point->z, ctx->two, ctx); + ec_powm (t1, point->z, mpi_const (MPI_C_TWO), ctx); ec_subm (l1, point->x, t1, ctx); - ec_mulm (l1, l1, ctx->three, ctx); + ec_mulm (l1, l1, mpi_const (MPI_C_THREE), ctx); ec_addm (t2, point->x, t1, ctx); ec_mulm (l1, l1, t2, ctx); } @@ -573,32 +554,32 @@ _gcry_mpi_ec_dup_point (mpi_point_t result, mpi_point_t point, mpi_ec_t ctx) { /* L1 = 3X^2 + aZ^4 */ /* T1: used for aZ^4. */ - ec_powm (l1, point->x, ctx->two, ctx); - ec_mulm (l1, l1, ctx->three, ctx); - ec_powm (t1, point->z, ctx->four, ctx); + ec_powm (l1, point->x, mpi_const (MPI_C_TWO), ctx); + ec_mulm (l1, l1, mpi_const (MPI_C_THREE), ctx); + ec_powm (t1, point->z, mpi_const (MPI_C_FOUR), ctx); ec_mulm (t1, t1, ctx->a, ctx); ec_addm (l1, l1, t1, ctx); } /* Z3 = 2YZ */ ec_mulm (z3, point->y, point->z, ctx); - ec_mulm (z3, z3, ctx->two, ctx); + ec_mulm (z3, z3, mpi_const (MPI_C_TWO), ctx); /* L2 = 4XY^2 */ /* T2: used for Y2; required later. */ - ec_powm (t2, point->y, ctx->two, ctx); + ec_powm (t2, point->y, mpi_const (MPI_C_TWO), ctx); ec_mulm (l2, t2, point->x, ctx); - ec_mulm (l2, l2, ctx->four, ctx); + ec_mulm (l2, l2, mpi_const (MPI_C_FOUR), ctx); /* X3 = L1^2 - 2L2 */ /* T1: used for L2^2. */ - ec_powm (x3, l1, ctx->two, ctx); - ec_mulm (t1, l2, ctx->two, ctx); + ec_powm (x3, l1, mpi_const (MPI_C_TWO), ctx); + ec_mulm (t1, l2, mpi_const (MPI_C_TWO), ctx); ec_subm (x3, x3, t1, ctx); /* L3 = 8Y^4 */ /* T2: taken from above. */ - ec_powm (t2, t2, ctx->two, ctx); - ec_mulm (l3, t2, ctx->eight, ctx); + ec_powm (t2, t2, mpi_const (MPI_C_TWO), ctx); + ec_mulm (l3, t2, mpi_const (MPI_C_EIGHT), ctx); /* Y3 = L1(L2 - X3) - L3 */ ec_subm (y3, l2, x3, ctx); @@ -676,23 +657,23 @@ _gcry_mpi_ec_add_points (mpi_point_t result, mpi_set (l1, x1); else { - ec_powm (l1, z2, ctx->two, ctx); + ec_powm (l1, z2, mpi_const (MPI_C_TWO), ctx); ec_mulm (l1, l1, x1, ctx); } if (z1_is_one) mpi_set (l2, x1); else { - ec_powm (l2, z1, ctx->two, ctx); + ec_powm (l2, z1, mpi_const (MPI_C_TWO), ctx); ec_mulm (l2, l2, x2, ctx); } /* l3 = l1 - l2 */ ec_subm (l3, l1, l2, ctx); /* l4 = y1 z2^3 */ - ec_powm (l4, z2, ctx->three, ctx); + ec_powm (l4, z2, mpi_const (MPI_C_THREE), ctx); ec_mulm (l4, l4, y1, ctx); /* l5 = y2 z1^3 */ - ec_powm (l5, z1, ctx->three, ctx); + ec_powm (l5, z1, mpi_const (MPI_C_THREE), ctx); ec_mulm (l5, l5, y2, ctx); /* l6 = l4 - l5 */ ec_subm (l6, l4, l5, ctx); @@ -722,16 +703,16 @@ _gcry_mpi_ec_add_points (mpi_point_t result, ec_mulm (z3, z1, z2, ctx); ec_mulm (z3, z3, l3, ctx); /* x3 = l6^2 - l7 l3^2 */ - ec_powm (t1, l6, ctx->two, ctx); - ec_powm (t2, l3, ctx->two, ctx); + ec_powm (t1, l6, mpi_const (MPI_C_TWO), ctx); + ec_powm (t2, l3, mpi_const (MPI_C_TWO), ctx); ec_mulm (t2, t2, l7, ctx); ec_subm (x3, t1, t2, ctx); /* l9 = l7 l3^2 - 2 x3 */ - ec_mulm (t1, x3, ctx->two, ctx); + ec_mulm (t1, x3, mpi_const (MPI_C_TWO), ctx); ec_subm (l9, t2, t1, ctx); /* y3 = (l9 l6 - l8 l3^3)/2 */ ec_mulm (l9, l9, l6, ctx); - ec_powm (t1, l3, ctx->three, ctx); /* fixme: Use saved value*/ + ec_powm (t1, l3, mpi_const (MPI_C_THREE), ctx); /* fixme: Use saved value*/ ec_mulm (t1, t1, l8, ctx); ec_subm (y3, l9, t1, ctx); ec_mulm (y3, y3, ctx->two_inv_p, ctx); @@ -824,9 +805,9 @@ _gcry_mpi_ec_mul_point (mpi_point_t result, mpi_free (z2); mpi_free (z3); } - z1 = mpi_copy (ctx->one); + z1 = mpi_copy (mpi_const (MPI_C_ONE)); - mpi_mul (h, k, ctx->three); /* h = 3k */ + mpi_mul (h, k, mpi_const (MPI_C_THREE)); /* h = 3k */ loops = mpi_get_nbits (h); mpi_set (result->x, point->x); diff --git a/mpi/mpiutil.c b/mpi/mpiutil.c index 64a2f7e1..cff15b74 100644 --- a/mpi/mpiutil.c +++ b/mpi/mpiutil.c @@ -28,6 +28,10 @@ #include "mpi-internal.h" #include "mod-source-info.h" +/* Constatns allocated right away at strtartup. */ +static gcry_mpi_t constants[MPI_NUMBER_OF_CONSTANTS]; + + const char * _gcry_mpi_get_hw_config (void) @@ -36,6 +40,34 @@ _gcry_mpi_get_hw_config (void) } +/* Initialize the MPI subsystem. This is called early and allows to + do some initialization without taking care of threading issues. */ +gcry_err_code_t +_gcry_mpi_init (void) +{ + int idx; + unsigned long value; + + for (idx=0; idx < MPI_NUMBER_OF_CONSTANTS; idx++) + { + switch (idx) + { + case MPI_C_ZERO: value = 0; break; + case MPI_C_ONE: value = 1; break; + case MPI_C_TWO: value = 2; break; + case MPI_C_THREE: value = 3; break; + case MPI_C_FOUR: value = 4; break; + case MPI_C_EIGHT: value = 8; break; + default: log_bug ("invalid mpi_const selector %d\n", idx); + } + constants[idx] = mpi_alloc_set_ui (value); + constants[idx]->flags = (16|32); + } + + return 0; +} + + /**************** * Note: It was a bad idea to use the number of limbs to allocate * because on a alpha the limbs are large but we normally need @@ -178,6 +210,8 @@ _gcry_mpi_free( gcry_mpi_t a ) { if (!a ) return; + if ((a->flags & 32)) + return; /* Never release a constant. */ if ((a->flags & 4)) gcry_free( a->d ); else @@ -195,7 +229,7 @@ _gcry_mpi_free( gcry_mpi_t a ) void _gcry_mpi_immutable_failed (void) { - log_info ("Warning: trying to change immutable MPI\n"); + log_info ("Warning: trying to change an immutable MPI\n"); } @@ -226,6 +260,12 @@ gcry_mpi_set_opaque( gcry_mpi_t a, void *p, unsigned int nbits ) if (!a) a = mpi_alloc(0); + if (mpi_is_immutable (a)) + { + mpi_immutable_failed (); + return a; + } + if( a->flags & 4 ) gcry_free( a->d ); else @@ -266,6 +306,7 @@ gcry_mpi_copy( gcry_mpi_t a ) : gcry_xmalloc( (a->sign+7)/8 ); memcpy( p, a->d, (a->sign+7)/8 ); b = gcry_mpi_set_opaque( NULL, p, a->sign ); + b->flags &= ~(16|32); /* Reset the immutable and constant flags. */ } else if( a ) { b = mpi_is_secure(a)? mpi_alloc_secure( a->nlimbs ) @@ -273,6 +314,7 @@ gcry_mpi_copy( gcry_mpi_t a ) b->nlimbs = a->nlimbs; b->sign = a->sign; b->flags = a->flags; + b->flags &= ~(16|32); /* Reset the immutable and constant flags. */ for(i=0; i < b->nlimbs; i++ ) b->d[i] = a->d[i]; } @@ -478,24 +520,30 @@ gcry_mpi_randomize( gcry_mpi_t w, void -gcry_mpi_set_flag( gcry_mpi_t a, enum gcry_mpi_flag flag ) +gcry_mpi_set_flag (gcry_mpi_t a, enum gcry_mpi_flag flag) { - switch( flag ) { - case GCRYMPI_FLAG_SECURE: mpi_set_secure(a); break; - case GCRYMPI_FLAG_IMMUTABLE: a->flags |= 16; break; - case GCRYMPI_FLAG_OPAQUE: - default: log_bug("invalid flag value\n"); + switch (flag) + { + case GCRYMPI_FLAG_SECURE: mpi_set_secure(a); break; + case GCRYMPI_FLAG_CONST: a->flags |= (16|32); break; + case GCRYMPI_FLAG_IMMUTABLE: a->flags |= 16; break; + case GCRYMPI_FLAG_OPAQUE: + default: log_bug("invalid flag value\n"); } } void -gcry_mpi_clear_flag( gcry_mpi_t a, enum gcry_mpi_flag flag ) +gcry_mpi_clear_flag (gcry_mpi_t a, enum gcry_mpi_flag flag) { (void)a; /* Not yet used. */ switch (flag) { - case GCRYMPI_FLAG_IMMUTABLE: a->flags &= ~16; break; + case GCRYMPI_FLAG_IMMUTABLE: + if (!(a->flags & 32)) + a->flags &= ~16; + break; + case GCRYMPI_FLAG_CONST: case GCRYMPI_FLAG_SECURE: case GCRYMPI_FLAG_OPAQUE: default: log_bug("invalid flag value\n"); @@ -503,15 +551,30 @@ gcry_mpi_clear_flag( gcry_mpi_t a, enum gcry_mpi_flag flag ) } int -gcry_mpi_get_flag( gcry_mpi_t a, enum gcry_mpi_flag flag ) +gcry_mpi_get_flag (gcry_mpi_t a, enum gcry_mpi_flag flag) { switch (flag) { - case GCRYMPI_FLAG_SECURE: return (a->flags & 1); - case GCRYMPI_FLAG_OPAQUE: return (a->flags & 4); - case GCRYMPI_FLAG_IMMUTABLE: return (a->flags & 16); + case GCRYMPI_FLAG_SECURE: return !!(a->flags & 1); + case GCRYMPI_FLAG_OPAQUE: return !!(a->flags & 4); + case GCRYMPI_FLAG_IMMUTABLE: return !!(a->flags & 16); + case GCRYMPI_FLAG_CONST: return !!(a->flags & 32); default: log_bug("invalid flag value\n"); } /*NOTREACHED*/ return 0; } + + +/* Return a constant MPI descripbed by NO which is one of the + MPI_C_xxx macros. There is no need to copy this returned value; it + may be used directly. */ +gcry_mpi_t +_gcry_mpi_const (enum gcry_mpi_constants no) +{ + if ((int)no < 0 || no > MPI_NUMBER_OF_CONSTANTS) + log_bug("invalid mpi_const selector %d\n", no); + if (!constants[no]) + log_bug("MPI subsystem not initialized\n"); + return constants[no]; +} |