ength).  */
    GCRYMPI_FMT_HEX = 4,    /* Hex format. */
    GCRYMPI_FMT_USG = 5,    /* Like STD but unsigned. */
    GCRYMPI_FMT_OPAQUE = 8  /* Opaque format (some functions only).  */
  };

/* Flags used for creating big integers.  */
enum gcry_mpi_flag
  {
    GCRYMPI_FLAG_SECURE = 1,  /* Allocate the number in "secure" memory.  */
    GCRYMPI_FLAG_OPAQUE = 2,  /* The number is not a real one but just
                                 a way to store some bytes.  This is
                                 useful for encrypted big integers.  */
    GCRYMPI_FLAG_IMMUTABLE = 4, /* Mark the MPI as immutable.  */
    GCRYMPI_FLAG_CONST     = 8, /* Mark the MPI as a constant.  */
    GCRYMPI_FLAG_USER1 = 0x0100,/* User flag 1.  */
    GCRYMPI_FLAG_USER2 = 0x0200,/* User flag 2.  */
    GCRYMPI_FLAG_USER3 = 0x0400,/* User flag 3.  */
    GCRYMPI_FLAG_USER4 = 0x0800 /* User flag 4.  */
  };


/* Macros to return pre-defined MPI constants.  */
#define GCRYMPI_CONST_ONE   (_gcry_mpi_get_const (1))
#define GCRYMPI_CONST_TWO   (_gcry_mpi_get_const (2))
#define GCRYMPI_CONST_THREE (_gcry_mpi_get_const (3))
#define GCRYMPI_CONST_FOUR  (_gcry_mpi_get_const (4))
#define GCRYMPI_CONST_EIGHT (_gcry_mpi_get_const (8))

/* Allocate a new big integer object, initialize it with 0 and
   initially allocate memory for a number of at least NBITS. */
gcry_mpi_t gcry_mpi_new (unsigned int nbits);

/* Same as gcry_mpi_new() but allocate in "secure" memory. */
gcry_mpi_t gcry_mpi_snew (unsigned int nbits);

/* Release the number A and free all associated resources. */
void gcry_mpi_release (gcry_mpi_t a);

/* Create a new number with the same value as A. */
gcry_mpi_t gcry_mpi_copy (const gcry_mpi_t a);

/* Store the big integer value U in W and release U.  */
void gcry_mpi_snatch (gcry_mpi_t w, gcry_mpi_t u);

/* Store the big integer value U in W. */
gcry_mpi_t gcry_mpi_set (gcry_mpi_t w, const gcry_mpi_t u);

/* Store the unsigned integer value U in W. */
gcry_mpi_t gcry_mpi_set_ui (gcry_mpi_t w, unsigned long u);

/* Store U as an unsigned int at W or return GPG_ERR_ERANGE. */
gpg_error_t gcry_mpi_get_ui (unsigned int *w, gcry_mpi_t u);

/* Swap the values of A and B. */
void gcry_mpi_swap (gcry_mpi_t a, gcry_mpi_t b);

/* Return 1 if A is negative; 0 if zero or positive.  */
int gcry_mpi_is_neg (gcry_mpi_t a);

/* W = - U */
void gcry_mpi_neg (gcry_mpi_t w, gcry_mpi_t u);

/* W = [W] */
void gcry_mpi_abs (gcry_mpi_t w);

/* Compare the big integer number U and V returning 0 for equality, a
   positive value for U > V and a negative for U < V. */
int gcry_mpi_cmp (const gcry_mpi_t u, const gcry_mpi_t v);

/* Compare the big integer number U with the unsigned integer V
   returning 0 for equality, a positive value for U > V and a negative
   for U < V. */
int gcry_mpi_cmp_ui (const gcry_mpi_t u, unsigned long v);

/* Convert the external representation of an integer stored in BUFFER
   with a length of BUFLEN into a newly create MPI returned in
   RET_MPI.  If NSCANNED is not NULL, it will receive the number of
   bytes actually scanned after a successful operation. */
gcry_error_t gcry_mpi_scan (gcry_mpi_t *ret_mpi, enum gcry_mpi_format format,
                            const void *buffer, size_t buflen,
                            size_t *nscanned);

/* Convert the big integer A into the external representation
   described by FORMAT and store it in the provided BUFFER which has
   been allocated by the user with a size of BUFLEN bytes.  NWRITTEN
   receives the actual length of the external representation unless it
   has been passed as NULL. */
gcry_error_t gcry_mpi_print (enum gcry_mpi_format format,
                             unsigned char *buffer, size_t buflen,
                             size_t *nwritten,
                             const gcry_mpi_t a);

/* Convert the big integer A into the external representation described
   by FORMAT and store it in a newly allocated buffer which address
   will be put into BUFFER.  NWRITTEN receives the actual lengths of the
   external representation. */
gcry_error_t gcry_mpi_aprint (enum gcry_mpi_format format,
                              unsigned char **buffer, size_t *nwritten,
                              const gcry_mpi_t a);

/* Dump the value of A in a format suitable for debugging to
   Libgcrypt's logging stream.  Note that one leading space but no
   trailing space or linefeed will be printed.  It is okay to pass
   NULL for A. */
void gcry_mpi_dump (const gcry_mpi_t a);


/* W = U + V.  */
void gcry_mpi_add (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v);

/* W = U + V.  V is an unsigned integer. */
void gcry_mpi_add_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v);

/* W = U + V mod M. */
void gcry_mpi_addm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m);

/* W = U - V. */
void gcry_mpi_sub (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v);

/* W = U - V.  V is an unsigned integer. */
void gcry_mpi_sub_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v );

/* W = U - V mod M */
void gcry_mpi_subm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m);

/* W = U * V. */
void gcry_mpi_mul (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v);

/* W = U * V.  V is an unsigned integer. */
void gcry_mpi_mul_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v );

/* W = U * V mod M. */
void gcry_mpi_mulm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m);

/* W = U * (2 ^ CNT). */
void gcry_mpi_mul_2exp (gcry_mpi_t w, gcry_mpi_t u, unsigned long cnt);

/* Q = DIVIDEND / DIVISOR, R = DIVIDEND % DIVISOR,
   Q or R may be passed as NULL.  ROUND should be negative or 0. */
void gcry_mpi_div (gcry_mpi_t q, gcry_mpi_t r,
                   gcry_mpi_t dividend, gcry_mpi_t divisor, int round);

/* R = DIVIDEND % DIVISOR */
void gcry_mpi_mod (gcry_mpi_t r, gcry_mpi_t dividend, gcry_mpi_t divisor);

/* W = B ^ E mod M. */
void gcry_mpi_powm (gcry_mpi_t w,
                    const gcry_mpi_t b, const gcry_mpi_t e,
                    const gcry_mpi_t m);

/* Set G to the greatest common divisor of A and B.
   Return true if the G is 1. */
int gcry_mpi_gcd (gcry_mpi_t g, gcry_mpi_t a, gcry_mpi_t b);

/* Set X to the multiplicative inverse of A mod M.
   Return true if the value exists. */
int gcry_mpi_invm (gcry_mpi_t x, gcry_mpi_t a, gcry_mpi_t m);

/* Create a new point object.  NBITS is usually 0.  */
gcry_mpi_point_t gcry_mpi_point_new (unsigned int nbits);

/* Release the object POINT.  POINT may be NULL. */
void gcry_mpi_point_release (gcry_mpi_point_t point);

/* Return a copy of POINT. */
gcry_mpi_point_t gcry_mpi_point_copy (gcry_mpi_point_t point);

/* Store the projective coordinates from POINT into X, Y, and Z.  */
void gcry_mpi_point_get (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t z,
                         gcry_mpi_point_t point);

/* Store the projective coordinates from POINT into X, Y, and Z and
   release POINT.  */
void gcry_mpi_point_snatch_get (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t z,
                                gcry_mpi_point_t point);

/* Store the projective coordinates X, Y, and Z into POINT.  */
gcry_mpi_point_t gcry_mpi_point_set (gcry_mpi_point_t point,
                                     gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t z);

/* Store the projective coordinates X, Y, and Z into POINT and release
   X, Y, and Z.  */
gcry_mpi_point_t gcry_mpi_point_snatch_set (gcry_mpi_point_t point,
                                            gcry_mpi_t x, gcry_mpi_t y,
                                            gcry_mpi_t z);

/* Allocate a new context for elliptic curve operations based on the
   parameters given by KEYPARAM or using CURVENAME.  */
gpg_error_t gcry_mpi_ec_new (gcry_ctx_t *r_ctx,
                             gcry_sexp_t keyparam, const char *curvename);

/* Get a named MPI from an elliptic curve context.  */
gcry_mpi_t gcry_mpi_ec_get_mpi (const char *name, gcry_ctx_t ctx, int copy);

/* Get a named point from an elliptic curve context.  */
gcry_mpi_point_t gcry_mpi_ec_get_point (const char *name,
                                        gcry_ctx_t ctx, int copy);

/* Store a named MPI into an elliptic curve context.  */
gpg_error_t gcry_mpi_ec_set_mpi (const char *name, gcry_mpi_t newvalue,
                                 gcry_ctx_t ctx);

/* Store a named point into an elliptic curve context.  */
gpg_error_t gcry_mpi_ec_set_point (const char *name, gcry_mpi_point_t newvalue,
                                   gcry_ctx_t ctx);

/* Decode and store VALUE into RESULT.  */
gpg_error_t gcry_mpi_ec_decode_point (gcry_mpi_point_t result,
                                      gcry_mpi_t value, gcry_ctx_t ctx);

/* Store the affine coordinates of POINT into X and Y.  */
int gcry_mpi_ec_get_affine (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_point_t point,
                            gcry_ctx_t ctx);

/* W = 2 * U.  */
void gcry_mpi_ec_dup (gcry_mpi_point_t w, gcry_mpi_point_t u, gcry_ctx_t ctx);

/* W = U + V.  */
void gcry_mpi_ec_add (gcry_mpi_point_t w,
                      gcry_mpi_point_t u, gcry_mpi_point_t v, gcry_ctx_t ctx);

/* W = U - V.  */
void gcry_mpi_ec_sub (gcry_mpi_point_t w,
                      gcry_mpi_point_t u, gcry_mpi_point_t v, gcry_ctx_t ctx);

/* W = N * U.  */
void gcry_mpi_ec_mul (gcry_mpi_point_t w, gcry_mpi_t n, gcry_mpi_point_t u,
                      gcry_ctx_t ctx);

/* Return true if POINT is on the curve described by CTX.  */
int gcry_mpi_ec_curve_point (gcry_mpi_point_t w, gcry_ctx_t ctx);

/* Return the number of bits required to represent A. */
unsigned int gcry_mpi_get_nbits (gcry_mpi_t a);

/* Return true when bit number N (counting from 0) is set in A. */
int      gcry_mpi_test_bit (gcry_mpi_t a, unsigned int n);

/* Set bit number N in A. */
void     gcry_mpi_set_bit (gcry_mpi_t a, unsigned int n);

/* Clear bit number N in A. */
void     gcry_mpi_clear_bit (gcry_mpi_t a, unsigned int n);

/* Set bit number N in A and clear all bits greater than N. */
void     gcry_mpi_set_highbit (gcry_mpi_t a, unsigned int n);

/* Clear bit number N in A and all bits greater than N. */
void     gcry_mpi_clear_highbit (gcry_mpi_t a, unsigned int n);

/* Shift the value of A by N bits to the right and store the result in X. */
void     gcry_mpi_rshift (gcry_mpi_t x, gcry_mpi_t a, unsigned int n);

/* Shift the value of A by N bits to the left and store the result in X. */
void     gcry_mpi_lshift (gcry_mpi_t x, gcry_mpi_t a, unsigned int n);

/* Store NBITS of the value P points to in A and mark A as an opaque
   value.  On success A received the the ownership of the value P.
   WARNING: Never use an opaque MPI for anything thing else than
   gcry_mpi_release, gcry_mpi_get_opaque. */
gcry_mpi_t gcry_mpi_set_opaque (gcry_mpi_t a, void *p, unsigned int nbits);

/* Store NBITS of the value P points to in A and mark A as an opaque
   value.  The function takes a copy of the provided value P.
   WARNING: Never use an opaque MPI for anything thing else than
   gcry_mpi_release, gcry_mpi_get_opaque. */
gcry_mpi_t gcry_mpi_set_opaque_copy (gcry_mpi_t a,
                                     const void *p, unsigned int nbits);

/* Return a pointer to an opaque value stored in A and return its size
   in NBITS.  Note that the returned pointer is still owned by A and
   that the function should never be used for an non-opaque MPI. */
void *gcry_mpi_get_opaque (gcry_mpi_t a, unsigned int *nbits);

/* Set the FLAG for the big integer A.  Currently only the flag
   GCRYMPI_FLAG_SECURE is allowed to convert A into an big intger
   stored in "secure" memory. */
void gcry_mpi_set_flag (gcry_mpi_t a, enum gcry_mpi_flag flag);

/* Clear FLAG for the big integer A.  Note that this function is
   currently useless as no flags are allowed. */
void gcry_mpi_clear_flag (gcry_mpi_t a, enum gcry_mpi_flag flag);

/* Return true if the FLAG is set for A. */
int gcry_mpi_get_flag (gcry_mpi_t a, enum gcry_mpi_flag flag);

/* Private function - do not use.  */
gcry_mpi_t _gcry_mpi_get_const (int no);

/* Unless the GCRYPT_NO_MPI_MACROS is used, provide a couple of
   convenience macros for the big integer functions. */
#ifndef GCRYPT_NO_MPI_MACROS
#define mpi_new(n)          gcry_mpi_new( (n) )
#define mpi_secure_new( n ) gcry_mpi_snew( (n) )
#define mpi_release(a)      \
  do \
    { \
      gcry_mpi_release ((a)); \
      (a) = NULL; \
    } \
  while (0)

#define mpi_copy( a )          gcry_mpi_copy( (a) )
#define mpi_snatch( w, u)      gcry_mpi_snatch( (w), (u) )
#define mpi_set( w, u)         gcry_mpi_set( (w), (u) )
#define mpi_set_ui( w, u)      gcry_mpi_set_ui( (w), (u) )
#define mpi_get_ui( w, u)      gcry_mpi_get_ui( (w), (u) )
#define mpi_abs( w )           gcry_mpi_abs( (w) )
#define mpi_neg( w, u)         gcry_mpi_neg( (w), (u) )
#define mpi_cmp( u, v )        gcry_mpi_cmp( (u), (v) )
#define mpi_cmp_ui( u, v )     gcry_mpi_cmp_ui( (u), (v) )
#define mpi_is_neg( a )        gcry_mpi_is_neg ((a))

#define mpi_add_ui(w,u,v)      gcry_mpi_add_ui((w),(u),(v))
#define mpi_add(w,u,v)         gcry_mpi_add ((w),(u),(v))
#define mpi_addm(w,u,v,m)      gcry_mpi_addm ((w),(u),(v),(m))
#define mpi_sub_ui(w,u,v)      gcry_mpi_sub_ui ((w),(u),(v))
#define mpi_sub(w,u,v)         gcry_mpi_sub ((w),(u),(v))
#define mpi_subm(w,u,v,m)      gcry_mpi_subm ((w),(u),(v),(m))
#define mpi_mul_ui(w,u,v)      gcry_mpi_mul_ui ((w),(u),(v))
#define mpi_mul_2exp(w,u,v)    gcry_mpi_mul_2exp ((w),(u),(v))
#define mpi_mul(w,u,v)         gcry_mpi_mul ((w),(u),(v))
#define mpi_mulm(w,u,v,m)      gcry_mpi_mulm ((w),(u),(v),(m))
#define mpi_powm(w,b,e,m)      gcry_mpi_powm ( (w), (b), (e), (m) )
#define mpi_tdiv(q,r,a,m)      gcry_mpi_div ( (q), (r), (a), (m), 0)
#define mpi_fdiv(q,r,a,m)      gcry_mpi_div ( (q), (r), (a), (m), -1)
#define mpi_mod(r,a,m)         gcry_mpi_mod ((r), (a), (m))
#define mpi_gcd(g,a,b)         gcry_mpi_gcd ( (g), (a), (b) )
#define mpi_invm(g,a,b)        gcry_mpi_invm ( (g), (a), (b) )

#define mpi_point_new(n)              gcry_mpi_point_new((n))
#define mpi_point_release(p)                    \
  do                                            \
    {                                           \
      gcry_mpi_point_release ((p));             \
      (p) = NULL;                               \
    }                                           \
  while (0)
#define mpi_point_copy(p)             gcry_mpi_point_copy((p))
#define mpi_point_get(x,y,z,p)        gcry_mpi_point_get((x),(y),(z),(p))
#define mpi_point_snatch_get(x,y,z,p) gcry_mpi_point_snatch_get((x),(y),(z),(p))
#define mpi_point_set(p,x,y,z)        gcry_mpi_point_set((p),(x),(y),(z))
#define mpi_point_snatch_set(p,x,y,z) gcry_mpi_point_snatch_set((p),(x),(y),(z))

#define mpi_get_nbits(a)       gcry_mpi_get_nbits ((a))
#define mpi_test_bit(a,b)      gcry_mpi_test_bit ((a),(b))
#define mpi_set_bit(a,b)       gcry_mpi_set_bit ((a),(b))
#define mpi_set_highbit(a,b)   gcry_mpi_set_highbit ((a),(b))
#define mpi_clear_bit(a,b)     gcry_mpi_clear_bit ((a),(b))
#define mpi_clear_highbit(a,b) gcry_mpi_clear_highbit ((a),(b))
#define mpi_rshift(a,b,c)      gcry_mpi_rshift ((a),(b),(c))
#define mpi_lshift(a,b,c)      gcry_mpi_lshift ((a),(b),(c))

#define mpi_set_opaque(a,b,c)  gcry_mpi_set_opaque( (a), (b), (c) )
#define mpi_get_opaque(a,b)    gcry_mpi_get_opaque( (a), (b) )
#endif /* GCRYPT_NO_MPI_MACROS */


