]>
git.ipfire.org Git - thirdparty/strongswan.git/blob - programs/pluto/gcryptfix.c
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.1 2004/03/15 20:35:28 as 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
);