1/* mpi.h - Multi Precision Integers 2 * Copyright (C) 1994, 1996, 1998, 3 * 2001, 2002, 2003, 2005 Free Software Foundation, Inc. 4 * 5 * This file is part of Libgcrypt. 6 * 7 * Libgcrypt is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU Lesser general Public License as 9 * published by the Free Software Foundation; either version 2.1 of 10 * the License, or (at your option) any later version. 11 * 12 * Libgcrypt is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 20 * 21 * Note: This code is heavily based on the GNU MP Library. 22 * Actually it's the same code with only minor changes in the 23 * way the data is stored; this is to support the abstraction 24 * of an optional secure memory allocation which may be used 25 * to avoid revealing of sensitive data due to paging etc. 26 */ 27 28#ifndef G10_MPI_H 29#define G10_MPI_H 30 31#include <config.h> 32#include <stdio.h> 33#include <string.h> 34 35#include "types.h" 36#include "../mpi/mpi-asm-defs.h" 37 38#include "g10lib.h" 39 40#ifndef _GCRYPT_IN_LIBGCRYPT 41#error this file should only be used inside libgcrypt 42#endif 43 44#ifndef BITS_PER_MPI_LIMB 45#if BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_INT 46 typedef unsigned int mpi_limb_t; 47 typedef signed int mpi_limb_signed_t; 48#elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_LONG 49 typedef unsigned long int mpi_limb_t; 50 typedef signed long int mpi_limb_signed_t; 51#elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_LONG_LONG 52 typedef unsigned long long int mpi_limb_t; 53 typedef signed long long int mpi_limb_signed_t; 54#elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_SHORT 55 typedef unsigned short int mpi_limb_t; 56 typedef signed short int mpi_limb_signed_t; 57#else 58#error BYTES_PER_MPI_LIMB does not match any C type 59#endif 60#define BITS_PER_MPI_LIMB (8*BYTES_PER_MPI_LIMB) 61#endif /*BITS_PER_MPI_LIMB*/ 62 63#define DBG_MPI _gcry_get_debug_flag( 2 ); 64 65struct gcry_mpi 66{ 67 int alloced; /* Array size (# of allocated limbs). */ 68 int nlimbs; /* Number of valid limbs. */ 69 int sign; /* Indicates a negative number and is also used 70 for opaque MPIs to store the length. */ 71 unsigned int flags; /* Bit 0: Array to be allocated in secure memory space.*/ 72 /* Bit 2: the limb is a pointer to some m_alloced data.*/ 73 mpi_limb_t *d; /* Array with the limbs */ 74}; 75 76#define MPI_NULL NULL 77 78#define mpi_get_nlimbs(a) ((a)->nlimbs) 79#define mpi_is_neg(a) ((a)->sign) 80 81/*-- mpiutil.c --*/ 82 83#ifdef M_DEBUG 84# define mpi_alloc(n) _gcry_mpi_debug_alloc((n), M_DBGINFO( __LINE__ ) ) 85# define mpi_alloc_secure(n) _gcry_mpi_debug_alloc_secure((n), M_DBGINFO( __LINE__ ) ) 86# define mpi_free(a) _gcry_mpi_debug_free((a), M_DBGINFO(__LINE__) ) 87# define mpi_resize(a,b) _gcry_mpi_debug_resize((a),(b), M_DBGINFO(__LINE__) ) 88# define mpi_copy(a) _gcry_mpi_debug_copy((a), M_DBGINFO(__LINE__) ) 89 gcry_mpi_t _gcry_mpi_debug_alloc( unsigned nlimbs, const char *info ); 90 gcry_mpi_t _gcry_mpi_debug_alloc_secure( unsigned nlimbs, const char *info ); 91 void _gcry_mpi_debug_free( gcry_mpi_t a, const char *info ); 92 void _gcry_mpi_debug_resize( gcry_mpi_t a, unsigned nlimbs, const char *info ); 93 gcry_mpi_t _gcry_mpi_debug_copy( gcry_mpi_t a, const char *info ); 94#else 95# define mpi_alloc(n) _gcry_mpi_alloc((n) ) 96# define mpi_alloc_secure(n) _gcry_mpi_alloc_secure((n) ) 97# define mpi_free(a) _gcry_mpi_free((a) ) 98# define mpi_resize(a,b) _gcry_mpi_resize((a),(b)) 99# define mpi_copy(a) _gcry_mpi_copy((a)) 100 gcry_mpi_t _gcry_mpi_alloc( unsigned nlimbs ); 101 gcry_mpi_t _gcry_mpi_alloc_secure( unsigned nlimbs ); 102 void _gcry_mpi_free( gcry_mpi_t a ); 103 void _gcry_mpi_resize( gcry_mpi_t a, unsigned nlimbs ); 104 gcry_mpi_t _gcry_mpi_copy( gcry_mpi_t a ); 105#endif 106 107#define mpi_is_opaque(a) ((a) && ((a)->flags&4)) 108#define mpi_is_secure(a) ((a) && ((a)->flags&1)) 109#define mpi_clear(a) _gcry_mpi_clear ((a)) 110#define mpi_alloc_like(a) _gcry_mpi_alloc_like((a)) 111#define mpi_set(a,b) _gcry_mpi_set ((a),(b)) 112#define mpi_set_ui(a,b) _gcry_mpi_set_ui ((a),(b)) 113#define mpi_get_ui(a,b) _gcry_mpi_get_ui ((a),(b)) 114#define mpi_alloc_set_ui(a) _gcry_mpi_alloc_set_ui ((a)) 115#define mpi_m_check(a) _gcry_mpi_m_check ((a)) 116#define mpi_swap(a,b) _gcry_mpi_swap ((a),(b)) 117#define mpi_new(n) _gcry_mpi_new ((n)) 118#define mpi_snew(n) _gcry_mpi_snew ((n)) 119 120void _gcry_mpi_clear( gcry_mpi_t a ); 121gcry_mpi_t _gcry_mpi_alloc_like( gcry_mpi_t a ); 122gcry_mpi_t _gcry_mpi_alloc_set_ui( unsigned long u); 123gcry_err_code_t _gcry_mpi_get_ui (gcry_mpi_t w, ulong *u); 124void _gcry_mpi_m_check( gcry_mpi_t a ); 125void _gcry_mpi_swap( gcry_mpi_t a, gcry_mpi_t b); 126gcry_mpi_t _gcry_mpi_new (unsigned int nbits); 127gcry_mpi_t _gcry_mpi_snew (unsigned int nbits); 128 129/*-- mpicoder.c --*/ 130void _gcry_log_mpidump( const char *text, gcry_mpi_t a ); 131u32 _gcry_mpi_get_keyid( gcry_mpi_t a, u32 *keyid ); 132byte *_gcry_mpi_get_buffer( gcry_mpi_t a, unsigned *nbytes, int *sign ); 133byte *_gcry_mpi_get_secure_buffer( gcry_mpi_t a, unsigned *nbytes, int *sign ); 134void _gcry_mpi_set_buffer ( gcry_mpi_t a, const void *buffer, 135 unsigned int nbytes, int sign ); 136 137#define log_mpidump _gcry_log_mpidump 138 139/*-- mpi-add.c --*/ 140#define mpi_add_ui(w,u,v) gcry_mpi_add_ui((w),(u),(v)) 141#define mpi_add(w,u,v) gcry_mpi_add ((w),(u),(v)) 142#define mpi_addm(w,u,v,m) gcry_mpi_addm ((w),(u),(v),(m)) 143#define mpi_sub_ui(w,u,v) gcry_mpi_sub_ui ((w),(u),(v)) 144#define mpi_sub(w,u,v) gcry_mpi_sub ((w),(u),(v)) 145#define mpi_subm(w,u,v,m) gcry_mpi_subm ((w),(u),(v),(m)) 146 147 148/*-- mpi-mul.c --*/ 149#define mpi_mul_ui(w,u,v) gcry_mpi_mul_ui ((w),(u),(v)) 150#define mpi_mul_2exp(w,u,v) gcry_mpi_mul_2exp ((w),(u),(v)) 151#define mpi_mul(w,u,v) gcry_mpi_mul ((w),(u),(v)) 152#define mpi_mulm(w,u,v,m) gcry_mpi_mulm ((w),(u),(v),(m)) 153 154 155/*-- mpi-div.c --*/ 156#define mpi_fdiv_r_ui(a,b,c) _gcry_mpi_fdiv_r_ui((a),(b),(c)) 157#define mpi_fdiv_r(a,b,c) _gcry_mpi_fdiv_r((a),(b),(c)) 158#define mpi_fdiv_q(a,b,c) _gcry_mpi_fdiv_q((a),(b),(c)) 159#define mpi_fdiv_qr(a,b,c,d) _gcry_mpi_fdiv_qr((a),(b),(c),(d)) 160#define mpi_tdiv_r(a,b,c) _gcry_mpi_tdiv_r((a),(b),(c)) 161#define mpi_tdiv_qr(a,b,c,d) _gcry_mpi_tdiv_qr((a),(b),(c),(d)) 162#define mpi_tdiv_q_2exp(a,b,c) _gcry_mpi_tdiv_q_2exp((a),(b),(c)) 163#define mpi_divisible_ui(a,b) _gcry_mpi_divisible_ui((a),(b)) 164 165ulong _gcry_mpi_fdiv_r_ui( gcry_mpi_t rem, gcry_mpi_t dividend, ulong divisor ); 166void _gcry_mpi_fdiv_r( gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mpi_t divisor ); 167void _gcry_mpi_fdiv_q( gcry_mpi_t quot, gcry_mpi_t dividend, gcry_mpi_t divisor ); 168void _gcry_mpi_fdiv_qr( gcry_mpi_t quot, gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mpi_t divisor ); 169void _gcry_mpi_tdiv_r( gcry_mpi_t rem, gcry_mpi_t num, gcry_mpi_t den); 170void _gcry_mpi_tdiv_qr( gcry_mpi_t quot, gcry_mpi_t rem, gcry_mpi_t num, gcry_mpi_t den); 171void _gcry_mpi_tdiv_q_2exp( gcry_mpi_t w, gcry_mpi_t u, unsigned count ); 172int _gcry_mpi_divisible_ui(gcry_mpi_t dividend, ulong divisor ); 173 174 175/*-- mpi-mod.c --*/ 176#define mpi_mod(r,a,m) _gcry_mpi_mod ((r), (a), (m)) 177#define mpi_barrett_init(m,f) _gcry_mpi_barrett_init ((m),(f)) 178#define mpi_barrett_free(c) _gcry_mpi_barrett_free ((c)) 179#define mpi_mod_barrett(r,a,c) _gcry_mpi_mod_barrett ((r), (a), (c)) 180#define mpi_mul_barrett(r,u,v,c) _gcry_mpi_mul_barrett ((r), (u), (v), (c)) 181 182void _gcry_mpi_mod (gcry_mpi_t r, gcry_mpi_t dividend, gcry_mpi_t divisor); 183 184/* Context used with Barrett reduction. */ 185struct barrett_ctx_s; 186typedef struct barrett_ctx_s *mpi_barrett_t; 187 188mpi_barrett_t _gcry_mpi_barrett_init (gcry_mpi_t m, int copy); 189void _gcry_mpi_barrett_free (mpi_barrett_t ctx); 190void _gcry_mpi_mod_barrett (gcry_mpi_t r, gcry_mpi_t x, mpi_barrett_t ctx); 191void _gcry_mpi_mul_barrett (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, 192 mpi_barrett_t ctx); 193 194 195 196/*-- mpi-gcd.c --*/ 197 198/*-- mpi-mpow.c --*/ 199#define mpi_mulpowm(a,b,c,d) _gcry_mpi_mulpowm ((a),(b),(c),(d)) 200void _gcry_mpi_mulpowm( gcry_mpi_t res, gcry_mpi_t *basearray, gcry_mpi_t *exparray, gcry_mpi_t mod); 201 202/*-- mpi-cmp.c --*/ 203#define mpi_cmp_ui(a,b) gcry_mpi_cmp_ui ((a),(b)) 204#define mpi_cmp(a,b) gcry_mpi_cmp ((a),(b)) 205int gcry_mpi_cmp_ui( gcry_mpi_t u, ulong v ); 206int gcry_mpi_cmp( gcry_mpi_t u, gcry_mpi_t v ); 207 208/*-- mpi-scan.c --*/ 209#define mpi_trailing_zeros(a) _gcry_mpi_trailing_zeros ((a)) 210int _gcry_mpi_getbyte( gcry_mpi_t a, unsigned idx ); 211void _gcry_mpi_putbyte( gcry_mpi_t a, unsigned idx, int value ); 212unsigned _gcry_mpi_trailing_zeros( gcry_mpi_t a ); 213 214/*-- mpi-bit.c --*/ 215#define mpi_normalize(a) _gcry_mpi_normalize ((a)) 216#define mpi_get_nbits(a) gcry_mpi_get_nbits ((a)) 217#define mpi_test_bit(a,b) gcry_mpi_test_bit ((a),(b)) 218#define mpi_set_bit(a,b) gcry_mpi_set_bit ((a),(b)) 219#define mpi_set_highbit(a,b) gcry_mpi_set_highbit ((a),(b)) 220#define mpi_clear_bit(a,b) gcry_mpi_clear_bit ((a),(b)) 221#define mpi_clear_highbit(a,b) gcry_mpi_clear_highbit ((a),(b)) 222#define mpi_rshift(a,b,c) gcry_mpi_rshift ((a),(b),(c)) 223#define mpi_lshift(a,b,c) gcry_mpi_lshift ((a),(b),(c)) 224 225void _gcry_mpi_normalize( gcry_mpi_t a ); 226 227/*-- mpi-inv.c --*/ 228#define mpi_invm(a,b,c) _gcry_mpi_invm ((a),(b),(c)) 229 230/*-- ec.c --*/ 231 232/* Object to represent a point in projective coordinates. */ 233struct mpi_point_s; 234typedef struct mpi_point_s mpi_point_t; 235struct mpi_point_s 236{ 237 gcry_mpi_t x; 238 gcry_mpi_t y; 239 gcry_mpi_t z; 240}; 241 242/* Context used with elliptic curve functions. */ 243struct mpi_ec_ctx_s; 244typedef struct mpi_ec_ctx_s *mpi_ec_t; 245 246void _gcry_mpi_ec_point_init (mpi_point_t *p); 247void _gcry_mpi_ec_point_free (mpi_point_t *p); 248mpi_ec_t _gcry_mpi_ec_init (gcry_mpi_t p, gcry_mpi_t a); 249void _gcry_mpi_ec_free (mpi_ec_t ctx); 250int _gcry_mpi_ec_get_affine (gcry_mpi_t x, gcry_mpi_t y, mpi_point_t *point, 251 mpi_ec_t ctx); 252void _gcry_mpi_ec_dup_point (mpi_point_t *result, 253 mpi_point_t *point, mpi_ec_t ctx); 254void _gcry_mpi_ec_add_points (mpi_point_t *result, 255 mpi_point_t *p1, mpi_point_t *p2, 256 mpi_ec_t ctx); 257void _gcry_mpi_ec_mul_point (mpi_point_t *result, 258 gcry_mpi_t scalar, mpi_point_t *point, 259 mpi_ec_t ctx); 260 261 262 263#endif /*G10_MPI_H*/ 264