1 /* Routines to make gcrypt routines feel at home in Pluto.
2 * Copyright (C) 1999 D. Hugh Redelmeier.
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * RCSID $Id: gcryptfix.c,v 1.4 2000/05/20 19:43:55 dhr Exp $
21 #include "constants.h"
25 #include "gcryptfix.h" /* includes <gmp.h> "defs.h" "rnd.h" */
28 mpi_alloc( unsigned nlimbs UNUSED )
30 MPI n = alloc_bytes(sizeof *n, "mpi_alloc");
37 mpi_alloc_secure( unsigned nlimbs )
39 return mpi_alloc(nlimbs);
43 mpi_alloc_set_ui( unsigned long u)
45 MPI n = alloc_bytes(sizeof *n, "mpi_copy");
47 mpz_init_set_ui(n, u);
54 MPI n = alloc_bytes(sizeof *n, "mpi_copy");
68 mpi_divisible_ui(MPI dividend, ulong divisor )
74 rem = mpz_mod_ui(remtoo, dividend, divisor);
80 mpi_trailing_zeros( MPI a )
82 return mpz_scan1(a, 0);
86 mpi_get_nbits( MPI a )
88 return mpz_sizeinbase(a, 2);
92 mpi_test_bit( MPI a, unsigned n )
94 /* inspired by gmp/mpz/clrbit.c */
95 mp_size_t li = n / mp_bits_per_limb;
97 if (li >= a->_mp_size)
99 return (a->_mp_d[li] & ((mp_limb_t) 1 << (n % mp_bits_per_limb))) != 0;
103 mpi_set_bit( MPI a, unsigned n )
109 mpi_clear_bit( MPI a, unsigned n )
115 mpi_clear_highbit( MPI a, unsigned n )
117 /* This seems whacky, but what do I know. */
118 mpz_fdiv_r_2exp(a, a, n);
122 mpi_set_highbit( MPI a, unsigned n )
124 /* This seems whacky, but what do I know. */
125 mpz_fdiv_r_2exp(a, a, n+1);
130 mpi_set_buffer( MPI a, const u_char *buffer, unsigned nbytes, int sign )
132 /* this is a lot like n_to_mpz */
135 passert(sign == 0); /* we won't hit any negative numbers */
136 mpz_init_set_ui(a, 0);
138 for (i = 0; i != nbytes; i++)
140 mpz_mul_ui(a, a, 1 << BITS_PER_BYTE);
141 mpz_add_ui(a, a, buffer[i]);
146 get_random_bits(size_t nbits, int level UNUSED, int secure UNUSED)
148 size_t nbytes = (nbits+7)/8;
149 u_char *b = alloc_bytes(nbytes, "random bytes");
151 get_rnd_bytes(b, nbytes);
154 /**************** from gnupg-1.0.0/mpi/mpi-mpow.c
155 * RES = (BASE[0] ^ EXP[0]) * (BASE[1] ^ EXP[1]) * ... * mod M
157 #define barrett_mulm( w, u, v, m, y, k, r1, r2 ) mpi_mulm( (w), (u), (v), (m) )
160 build_index( MPI *exparray, int k, int i, int t )
166 for(j=k-1; j >= 0; j-- ) {
168 if( mpi_test_bit( exparray[j], bitno ) )
171 /*log_debug("t=%d i=%d index=%d\n", t, i, index );*/
176 mpi_mulpowm( MPI res, MPI *basearray, MPI *exparray, MPI m)
178 int k; /* number of elements */
179 int t; /* bit size of largest exponent */
181 MPI *G; /* table with precomputed values of size 2^k */
184 MPI barrett_y, barrett_r1, barrett_r2;
188 for(k=0; basearray[k]; k++ )
191 for(t=0, i=0; (tmp=exparray[i]); i++ ) {
192 /*log_mpidump("exp: ", tmp );*/
193 j = mpi_get_nbits(tmp);
197 /*log_mpidump("mod: ", m );*/
203 m_alloc_ptrs_clear(G, 1<<k);
205 G = m_alloc_clear( (1<<k) * sizeof *G );
209 barrett_y = init_barrett( m, &barrett_k, &barrett_r1, &barrett_r2 );
212 tmp = mpi_alloc( mpi_get_nlimbs(m)+1 );
213 mpi_set_ui( res, 1 );
214 for(i = 1; i <= t; i++ ) {
215 barrett_mulm(tmp, res, res, m, barrett_y, barrett_k,
216 barrett_r1, barrett_r2 );
217 idx = build_index( exparray, k, i, t );
218 passert( idx >= 0 && idx < (1<<k) );
221 G[0] = mpi_alloc_set_ui( 1 );
223 for(j=0; j < k; j++ ) {
224 if( (idx & (1<<j) ) ) {
226 G[idx] = mpi_copy( basearray[j] );
228 barrett_mulm( G[idx], G[idx], basearray[j],
229 m, barrett_y, barrett_k, barrett_r1, barrett_r2 );
233 G[idx] = mpi_alloc(0);
236 barrett_mulm(res, tmp, G[idx], m, barrett_y, barrett_k, barrett_r1, barrett_r2 );
243 mpi_free(barrett_r1);
244 mpi_free(barrett_r2);
246 for(i=0; i < (1<<k); i++ )
252 log_mpidump( const char *text UNUSED, MPI a )
254 /* Print number in hex -- helpful to see if they match bytes.
255 * Humans are not going to do arithmetic with the large numbers!
256 * Much code adapted from mpz_to_n.
258 u_char buf[8048]; /* this ought to be big enough */
259 size_t len = (mpz_sizeinbase(a, 16) + 1) / 2; /* bytes */
263 passert(len <= sizeof(buf));
270 for (i = len-1; i >= 0; i--)
272 buf[i] = mpz_mdivmod_ui(&temp2, NULL, &temp1, 1 << BITS_PER_BYTE);
273 mpz_set(&temp1, &temp2);
276 passert(mpz_sgn(&temp1) == 0); /* we must have done all the bits */
281 DBG_dump(text, buf, len);