import core of imath 1.1.9
git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@17471 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
3261
lib/des/imath/imath.c
Executable file
3261
lib/des/imath/imath.c
Executable file
File diff suppressed because it is too large
Load Diff
209
lib/des/imath/imath.h
Executable file
209
lib/des/imath/imath.h
Executable file
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
Name: imath.h
|
||||
Purpose: Arbitrary precision integer arithmetic routines.
|
||||
Author: M. J. Fromberger <http://www.dartmouth.edu/~sting/>
|
||||
Info: $Id$
|
||||
|
||||
Copyright (C) 2002 Michael J. Fromberger, All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation files
|
||||
(the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef IMATH_H_
|
||||
#define IMATH_H_
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
typedef unsigned char mp_sign;
|
||||
typedef unsigned int mp_size;
|
||||
typedef int mp_result;
|
||||
#ifdef USE_LONG_LONG
|
||||
typedef unsigned int mp_digit;
|
||||
typedef unsigned long long mp_word;
|
||||
#else
|
||||
typedef unsigned short mp_digit;
|
||||
typedef unsigned int mp_word;
|
||||
#endif
|
||||
|
||||
typedef struct mpz {
|
||||
mp_digit *digits;
|
||||
mp_size alloc;
|
||||
mp_size used;
|
||||
mp_sign sign;
|
||||
} mpz_t, *mp_int;
|
||||
|
||||
#define MP_DIGITS(Z) ((Z)->digits)
|
||||
#define MP_ALLOC(Z) ((Z)->alloc)
|
||||
#define MP_USED(Z) ((Z)->used)
|
||||
#define MP_SIGN(Z) ((Z)->sign)
|
||||
|
||||
extern const mp_result MP_OK;
|
||||
extern const mp_result MP_FALSE;
|
||||
extern const mp_result MP_TRUE;
|
||||
extern const mp_result MP_MEMORY;
|
||||
extern const mp_result MP_RANGE;
|
||||
extern const mp_result MP_UNDEF;
|
||||
extern const mp_result MP_TRUNC;
|
||||
extern const mp_result MP_BADARG;
|
||||
|
||||
#define MP_DIGIT_BIT (sizeof(mp_digit) * CHAR_BIT)
|
||||
#define MP_WORD_BIT (sizeof(mp_word) * CHAR_BIT)
|
||||
|
||||
#ifdef USE_LONG_LONG
|
||||
# ifndef ULONG_LONG_MAX
|
||||
# ifdef ULLONG_MAX
|
||||
# define ULONG_LONG_MAX ULLONG_MAX
|
||||
# else
|
||||
# error "Maximum value of unsigned long long not defined!"
|
||||
# endif
|
||||
# endif
|
||||
# define MP_DIGIT_MAX (ULONG_MAX * 1ULL)
|
||||
# define MP_WORD_MAX ULONG_LONG_MAX
|
||||
#else
|
||||
# define MP_DIGIT_MAX (USHRT_MAX * 1UL)
|
||||
# define MP_WORD_MAX (UINT_MAX * 1UL)
|
||||
#endif
|
||||
|
||||
#define MP_MIN_RADIX 2
|
||||
#define MP_MAX_RADIX 36
|
||||
|
||||
extern const mp_sign MP_NEG;
|
||||
extern const mp_sign MP_ZPOS;
|
||||
|
||||
#define mp_int_is_odd(Z) ((Z)->digits[0] & 1)
|
||||
#define mp_int_is_even(Z) !((Z)->digits[0] & 1)
|
||||
|
||||
mp_size mp_get_default_precision(void);
|
||||
void mp_set_default_precision(mp_size s);
|
||||
mp_size mp_get_multiply_threshold(void);
|
||||
void mp_set_multiply_threshold(mp_size s);
|
||||
|
||||
mp_result mp_int_init(mp_int z);
|
||||
mp_int mp_int_alloc(void);
|
||||
mp_result mp_int_init_size(mp_int z, mp_size prec);
|
||||
mp_result mp_int_init_copy(mp_int z, mp_int old);
|
||||
mp_result mp_int_init_value(mp_int z, int value);
|
||||
mp_result mp_int_set_value(mp_int z, int value);
|
||||
void mp_int_clear(mp_int z);
|
||||
void mp_int_free(mp_int z);
|
||||
|
||||
mp_result mp_int_copy(mp_int a, mp_int c); /* c = a */
|
||||
void mp_int_swap(mp_int a, mp_int c); /* swap a, c */
|
||||
void mp_int_zero(mp_int z); /* z = 0 */
|
||||
mp_result mp_int_abs(mp_int a, mp_int c); /* c = |a| */
|
||||
mp_result mp_int_neg(mp_int a, mp_int c); /* c = -a */
|
||||
mp_result mp_int_add(mp_int a, mp_int b, mp_int c); /* c = a + b */
|
||||
mp_result mp_int_add_value(mp_int a, int value, mp_int c);
|
||||
mp_result mp_int_sub(mp_int a, mp_int b, mp_int c); /* c = a - b */
|
||||
mp_result mp_int_sub_value(mp_int a, int value, mp_int c);
|
||||
mp_result mp_int_mul(mp_int a, mp_int b, mp_int c); /* c = a * b */
|
||||
mp_result mp_int_mul_value(mp_int a, int value, mp_int c);
|
||||
mp_result mp_int_mul_pow2(mp_int a, int p2, mp_int c);
|
||||
mp_result mp_int_sqr(mp_int a, mp_int c); /* c = a * a */
|
||||
mp_result mp_int_div(mp_int a, mp_int b, /* q = a / b */
|
||||
mp_int q, mp_int r); /* r = a % b */
|
||||
mp_result mp_int_div_value(mp_int a, int value, /* q = a / value */
|
||||
mp_int q, int *r); /* r = a % value */
|
||||
mp_result mp_int_div_pow2(mp_int a, int p2, /* q = a / 2^p2 */
|
||||
mp_int q, mp_int r); /* r = q % 2^p2 */
|
||||
mp_result mp_int_mod(mp_int a, mp_int m, mp_int c); /* c = a % m */
|
||||
#define mp_int_mod_value(A, V, R) mp_int_div_value((A), (V), 0, (R))
|
||||
mp_result mp_int_expt(mp_int a, int b, mp_int c); /* c = a^b */
|
||||
mp_result mp_int_expt_value(int a, int b, mp_int c); /* c = a^b */
|
||||
|
||||
int mp_int_compare(mp_int a, mp_int b); /* a <=> b */
|
||||
int mp_int_compare_unsigned(mp_int a, mp_int b); /* |a| <=> |b| */
|
||||
int mp_int_compare_zero(mp_int z); /* a <=> 0 */
|
||||
int mp_int_compare_value(mp_int z, int value); /* a <=> v */
|
||||
|
||||
/* Returns true if v|a, false otherwise (including errors) */
|
||||
int mp_int_divisible_value(mp_int a, int v);
|
||||
|
||||
/* Returns k >= 0 such that z = 2^k, if one exists; otherwise < 0 */
|
||||
int mp_int_is_pow2(mp_int z);
|
||||
|
||||
mp_result mp_int_exptmod(mp_int a, mp_int b, mp_int m,
|
||||
mp_int c); /* c = a^b (mod m) */
|
||||
mp_result mp_int_exptmod_evalue(mp_int a, int value,
|
||||
mp_int m, mp_int c); /* c = a^v (mod m) */
|
||||
mp_result mp_int_exptmod_bvalue(int value, mp_int b,
|
||||
mp_int m, mp_int c); /* c = v^b (mod m) */
|
||||
mp_result mp_int_exptmod_known(mp_int a, mp_int b,
|
||||
mp_int m, mp_int mu,
|
||||
mp_int c); /* c = a^b (mod m) */
|
||||
mp_result mp_int_redux_const(mp_int m, mp_int c);
|
||||
|
||||
mp_result mp_int_invmod(mp_int a, mp_int m, mp_int c); /* c = 1/a (mod m) */
|
||||
|
||||
mp_result mp_int_gcd(mp_int a, mp_int b, mp_int c); /* c = gcd(a, b) */
|
||||
|
||||
mp_result mp_int_egcd(mp_int a, mp_int b, mp_int c, /* c = gcd(a, b) */
|
||||
mp_int x, mp_int y); /* c = ax + by */
|
||||
|
||||
mp_result mp_int_sqrt(mp_int a, mp_int c); /* c = floor(sqrt(q)) */
|
||||
|
||||
/* Convert to an int, if representable (returns MP_RANGE if not). */
|
||||
mp_result mp_int_to_int(mp_int z, int *out);
|
||||
|
||||
/* Convert to nul-terminated string with the specified radix, writing at
|
||||
most limit characters including the nul terminator */
|
||||
mp_result mp_int_to_string(mp_int z, mp_size radix,
|
||||
char *str, int limit);
|
||||
|
||||
/* Return the number of characters required to represent
|
||||
z in the given radix. May over-estimate. */
|
||||
mp_result mp_int_string_len(mp_int z, mp_size radix);
|
||||
|
||||
/* Read zero-terminated string into z */
|
||||
mp_result mp_int_read_string(mp_int z, mp_size radix, const char *str);
|
||||
mp_result mp_int_read_cstring(mp_int z, mp_size radix, const char *str,
|
||||
char **end);
|
||||
|
||||
/* Return the number of significant bits in z */
|
||||
mp_result mp_int_count_bits(mp_int z);
|
||||
|
||||
/* Convert z to two's complement binary, writing at most limit bytes */
|
||||
mp_result mp_int_to_binary(mp_int z, unsigned char *buf, int limit);
|
||||
|
||||
/* Read a two's complement binary value into z from the given buffer */
|
||||
mp_result mp_int_read_binary(mp_int z, unsigned char *buf, int len);
|
||||
|
||||
/* Return the number of bytes required to represent z in binary. */
|
||||
mp_result mp_int_binary_len(mp_int z);
|
||||
|
||||
/* Convert z to unsigned binary, writing at most limit bytes */
|
||||
mp_result mp_int_to_unsigned(mp_int z, unsigned char *buf, int limit);
|
||||
|
||||
/* Read an unsigned binary value into z from the given buffer */
|
||||
mp_result mp_int_read_unsigned(mp_int z, unsigned char *buf, int len);
|
||||
|
||||
/* Return the number of bytes required to represent z as unsigned output */
|
||||
mp_result mp_int_unsigned_len(mp_int z);
|
||||
|
||||
/* Return a statically allocated string describing error code res */
|
||||
const char *mp_error_string(mp_result res);
|
||||
|
||||
#if DEBUG
|
||||
void s_print(char *tag, mp_int z);
|
||||
void s_print_buf(char *tag, mp_digit *buf, mp_size num);
|
||||
#endif
|
||||
|
||||
#endif /* end IMATH_H_ */
|
24
lib/des/imath/import.sh
Normal file
24
lib/des/imath/import.sh
Normal file
@@ -0,0 +1,24 @@
|
||||
#!/bin/sh
|
||||
# $Id$
|
||||
|
||||
dir=$1
|
||||
|
||||
if test ! -f "$dir"/imdrover.c ; then
|
||||
echo $dir doesnt seem to contain imath
|
||||
exit 1
|
||||
fi
|
||||
|
||||
rm *.[ch]
|
||||
|
||||
headers=`grep ^HDRS "$dir"/Makefile |sed 's/^HDRS=//' | sed 's/imdrover.h//'`
|
||||
code=`echo $headers | sed 's/\.h/.c/g'`
|
||||
|
||||
for a in $headers $code ; do
|
||||
cp "$dir"/"$a" .
|
||||
done
|
||||
|
||||
echo "imathsource = \\"
|
||||
for a in $headers $code ; do
|
||||
echo " imath/$a \\"
|
||||
done | sort
|
||||
|
1121
lib/des/imath/imrat.c
Executable file
1121
lib/des/imath/imrat.c
Executable file
File diff suppressed because it is too large
Load Diff
117
lib/des/imath/imrat.h
Executable file
117
lib/des/imath/imrat.h
Executable file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
Name: imrat.h
|
||||
Purpose: Arbitrary precision rational arithmetic routines.
|
||||
Author: M. J. Fromberger <http://www.dartmouth.edu/~sting/>
|
||||
Info: $Id$
|
||||
|
||||
Copyright (C) 2002 Michael J. Fromberger, All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation files
|
||||
(the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef IMRAT_H_
|
||||
#define IMRAT_H_
|
||||
|
||||
#include "imath.h"
|
||||
|
||||
typedef struct mpq {
|
||||
mpz_t num; /* Numerator */
|
||||
mpz_t den; /* Denominator, <> 0 */
|
||||
} mpq_t, *mp_rat;
|
||||
|
||||
#define MP_NUMER_P(Q) (&((Q)->num)) /* Pointer to numerator */
|
||||
#define MP_DENOM_P(Q) (&((Q)->den)) /* Pointer to denominator */
|
||||
|
||||
/* Rounding constants */
|
||||
extern const mp_result MP_ROUND_DOWN;
|
||||
extern const mp_result MP_ROUND_HALF_UP;
|
||||
extern const mp_result MP_ROUND_UP;
|
||||
extern const mp_result MP_ROUND_HALF_DOWN;
|
||||
|
||||
void mp_rat_set_rounding(mp_result rnd);
|
||||
mp_result mp_rat_get_rounding(void);
|
||||
|
||||
mp_result mp_rat_init(mp_rat r);
|
||||
mp_rat mp_rat_alloc(void);
|
||||
mp_result mp_rat_init_size(mp_rat r, mp_size n_prec, mp_size d_prec);
|
||||
mp_result mp_rat_init_copy(mp_rat r, mp_rat old);
|
||||
mp_result mp_rat_set_value(mp_rat r, int numer, int denom);
|
||||
void mp_rat_clear(mp_rat r);
|
||||
void mp_rat_free(mp_rat r);
|
||||
mp_result mp_rat_numer(mp_rat r, mp_int z); /* z = num(r) */
|
||||
mp_result mp_rat_denom(mp_rat r, mp_int z); /* z = den(r) */
|
||||
mp_sign mp_rat_sign(mp_rat r);
|
||||
|
||||
mp_result mp_rat_copy(mp_rat a, mp_rat c); /* c = a */
|
||||
void mp_rat_zero(mp_rat r); /* r = 0 */
|
||||
mp_result mp_rat_abs(mp_rat a, mp_rat c); /* c = |a| */
|
||||
mp_result mp_rat_neg(mp_rat a, mp_rat c); /* c = -a */
|
||||
mp_result mp_rat_recip(mp_rat a, mp_rat c); /* c = 1 / a */
|
||||
mp_result mp_rat_add(mp_rat a, mp_rat b, mp_rat c); /* c = a + b */
|
||||
mp_result mp_rat_sub(mp_rat a, mp_rat b, mp_rat c); /* c = a - b */
|
||||
mp_result mp_rat_mul(mp_rat a, mp_rat b, mp_rat c); /* c = a * b */
|
||||
mp_result mp_rat_div(mp_rat a, mp_rat b, mp_rat c); /* c = a / b */
|
||||
|
||||
mp_result mp_rat_add_int(mp_rat a, mp_int b, mp_rat c); /* c = a + b */
|
||||
mp_result mp_rat_sub_int(mp_rat a, mp_int b, mp_rat c); /* c = a - b */
|
||||
mp_result mp_rat_mul_int(mp_rat a, mp_int b, mp_rat c); /* c = a * b */
|
||||
mp_result mp_rat_div_int(mp_rat a, mp_int b, mp_rat c); /* c = a / b */
|
||||
mp_result mp_rat_expt(mp_rat a, int b, mp_rat c); /* c = a ^ b */
|
||||
|
||||
int mp_rat_compare(mp_rat a, mp_rat b); /* a <=> b */
|
||||
int mp_rat_compare_unsigned(mp_rat a, mp_rat b); /* |a| <=> |b| */
|
||||
int mp_rat_compare_zero(mp_rat r); /* r <=> 0 */
|
||||
int mp_rat_compare_value(mp_rat r, int n, int d); /* r <=> n/d */
|
||||
int mp_rat_is_integer(mp_rat r);
|
||||
|
||||
/* Convert to integers, if representable (returns MP_RANGE if not). */
|
||||
mp_result mp_rat_to_ints(mp_rat r, int *num, int *den);
|
||||
|
||||
/* Convert to nul-terminated string with the specified radix, writing
|
||||
at most limit characters including the nul terminator. */
|
||||
mp_result mp_rat_to_string(mp_rat r, mp_size radix, char *str, int limit);
|
||||
|
||||
/* Convert to decimal format in the specified radix and precision,
|
||||
writing at most limit characters including a nul terminator. */
|
||||
mp_result mp_rat_to_decimal(mp_rat r, mp_size radix, mp_size prec,
|
||||
char *str, int limit);
|
||||
|
||||
/* Return the number of characters required to represent r in the given
|
||||
radix. May over-estimate. */
|
||||
mp_result mp_rat_string_len(mp_rat r, mp_size radix);
|
||||
|
||||
/* Return the number of characters required to represent r in decimal
|
||||
format with the given radix and precision. May over-estimate. */
|
||||
mp_result mp_rat_decimal_len(mp_rat r, mp_size radix, mp_size prec);
|
||||
|
||||
/* Read zero-terminated string into r */
|
||||
mp_result mp_rat_read_string(mp_rat r, mp_size radix, const char *str);
|
||||
mp_result mp_rat_read_cstring(mp_rat r, mp_size radix, const char *str,
|
||||
char **end);
|
||||
mp_result mp_rat_read_ustring(mp_rat r, mp_size radix, const char *str,
|
||||
char **end);
|
||||
|
||||
/* Read zero-terminated string in decimal format into r */
|
||||
mp_result mp_rat_read_decimal(mp_rat r, mp_size radix, const char *str);
|
||||
mp_result mp_rat_read_cdecimal(mp_rat r, mp_size radix, const char *str,
|
||||
char **end);
|
||||
|
||||
#endif /* IMRAT_H_ */
|
110
lib/des/imath/iprime.c
Executable file
110
lib/des/imath/iprime.c
Executable file
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
Name: iprime.c
|
||||
Purpose: Pseudoprimality testing routines
|
||||
Author: M. J. Fromberger <http://www.dartmouth.edu/~sting/>
|
||||
Info: $Id$
|
||||
|
||||
Copyright (C) 2002 Michael J. Fromberger, All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation files
|
||||
(the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "iprime.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
static int s_ptab_size = 32;
|
||||
static int s_ptab[] = {
|
||||
2, 3, 5, 7, 11, 13, 17, 19,
|
||||
23, 29, 31, 37, 41, 43, 47, 53,
|
||||
59, 61, 67, 71, 73, 79, 83, 89,
|
||||
97, 101, 103, 107, 109, 113, 127, 131
|
||||
};
|
||||
|
||||
/* {{{ mp_int_is_prime(z) */
|
||||
|
||||
/* Test whether z is likely to be prime:
|
||||
MP_TRUE means it is probably prime
|
||||
MP_FALSE means it is definitely composite
|
||||
*/
|
||||
mp_result mp_int_is_prime(mp_int z)
|
||||
{
|
||||
int i, rem;
|
||||
mp_result res;
|
||||
|
||||
/* First check for divisibility by small primes; this eliminates a
|
||||
large number of composite candidates quickly
|
||||
*/
|
||||
for(i = 0; i < s_ptab_size; ++i) {
|
||||
if((res = mp_int_div_value(z, s_ptab[i], NULL, &rem)) != MP_OK)
|
||||
return res;
|
||||
|
||||
if(rem == 0)
|
||||
return MP_FALSE;
|
||||
}
|
||||
|
||||
/* Now try Fermat's test for several prime witnesses (since we now
|
||||
know from the above that z is not a multiple of any of them)
|
||||
*/
|
||||
{
|
||||
mpz_t tmp;
|
||||
|
||||
if((res = mp_int_init(&tmp)) != MP_OK) return res;
|
||||
|
||||
for(i = 0; i < 10 && i < s_ptab_size; ++i) {
|
||||
if((res = mp_int_exptmod_bvalue(s_ptab[i], z, z, &tmp)) != MP_OK)
|
||||
return res;
|
||||
|
||||
if(mp_int_compare_value(&tmp, s_ptab[i]) != 0) {
|
||||
mp_int_clear(&tmp);
|
||||
return MP_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
mp_int_clear(&tmp);
|
||||
}
|
||||
|
||||
return MP_TRUE;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ mp_int_find_prime(z) */
|
||||
|
||||
/* Find the first apparent prime in ascending order from z */
|
||||
mp_result mp_int_find_prime(mp_int z)
|
||||
{
|
||||
mp_result res;
|
||||
|
||||
if(mp_int_is_even(z) && ((res = mp_int_add_value(z, 1, z)) != MP_OK))
|
||||
return res;
|
||||
|
||||
while((res = mp_int_is_prime(z)) == MP_FALSE) {
|
||||
if((res = mp_int_add_value(z, 2, z)) != MP_OK)
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* Here there be dragons */
|
44
lib/des/imath/iprime.h
Executable file
44
lib/des/imath/iprime.h
Executable file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
Name: iprime.h
|
||||
Purpose: Pseudoprimality testing routines
|
||||
Author: M. J. Fromberger <http://www.dartmouth.edu/~sting/>
|
||||
Info: $Id$
|
||||
|
||||
Copyright (C) 2002 Michael J. Fromberger, All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation files
|
||||
(the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef IPRIME_H_
|
||||
#define IPRIME_H_
|
||||
|
||||
#include "imath.h"
|
||||
|
||||
/* Test whether z is likely to be prime
|
||||
MP_YES means it is probably prime
|
||||
MP_NO means it is definitely composite
|
||||
*/
|
||||
mp_result mp_int_is_prime(mp_int z);
|
||||
|
||||
/* Find the first apparent prime in ascending order from z */
|
||||
mp_result mp_int_find_prime(mp_int z);
|
||||
|
||||
#endif /* IPRIME_H_ */
|
205
lib/des/imath/rsamath.c
Executable file
205
lib/des/imath/rsamath.c
Executable file
@@ -0,0 +1,205 @@
|
||||
/*
|
||||
Name: rsamath.c
|
||||
Purpose: Implements part of PKCS#1, v. 2.1, June 14, 2002 (RSA Labs)
|
||||
Author: M. J. Fromberger <http://www.dartmouth.edu/~sting/>
|
||||
Copyright (C) 2002 Michael J. Fromberger, All Rights Reserved.
|
||||
Info: $Id$
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation files
|
||||
(the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "rsamath.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
static mp_result s_rsa_transform(mp_int msg, mp_int exp,
|
||||
mp_int mod, mp_int out);
|
||||
|
||||
/* {{{ rsa_i2osp(z, out, len) */
|
||||
|
||||
/* Convert integer to octet string, per PKCS#1 v.2.1 */
|
||||
mp_result rsa_i2osp(mp_int z, unsigned char *out, int len)
|
||||
{
|
||||
int excess_len = mp_int_binary_len(z);
|
||||
|
||||
if(excess_len < len)
|
||||
return MP_RANGE;
|
||||
|
||||
memset(out, 0, len);
|
||||
|
||||
excess_len -= len;
|
||||
mp_int_to_binary(z, out + excess_len, len);
|
||||
|
||||
return MP_OK;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ rsa_os2ip(z, in, len) */
|
||||
|
||||
/* Convert octet string to integer, per PKCS#1 v.2.1 */
|
||||
mp_result rsa_os2ip(mp_int z, unsigned char *in, int len)
|
||||
{
|
||||
return mp_int_read_binary(z, in, len);
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ rsa_rsaep(msg, exp, mod, cipher) */
|
||||
|
||||
/* Primitive RSA encryption operation */
|
||||
mp_result rsa_rsaep(mp_int msg, mp_int exp, mp_int mod, mp_int cipher)
|
||||
{
|
||||
return s_rsa_transform(msg, exp, mod, cipher);
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ rsa_rsadp(cipher, exp, mod, msg) */
|
||||
|
||||
/* Primitive RSA decryption operation */
|
||||
mp_result rsa_rsadp(mp_int cipher, mp_int exp, mp_int mod, mp_int msg)
|
||||
{
|
||||
return s_rsa_transform(cipher, exp, mod, msg);
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ rsa_rsasp(msg, exp, mod, signature) */
|
||||
|
||||
/* Primitive RSA signing operation */
|
||||
mp_result rsa_rsasp(mp_int msg, mp_int exp, mp_int mod, mp_int signature)
|
||||
{
|
||||
return s_rsa_transform(msg, exp, mod, signature);
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ rsa_rsavp(signature, exp, mod, msg) */
|
||||
|
||||
/* Primitive RSA verification operation */
|
||||
mp_result rsa_rsavp(mp_int signature, mp_int exp, mp_int mod, mp_int msg)
|
||||
{
|
||||
return s_rsa_transform(signature, exp, mod, msg);
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ rsa_max_message_len(mod) */
|
||||
|
||||
/* Compute the maximum length in bytes a message can have using PKCS#1
|
||||
v.1.5 encoding with the given modulus */
|
||||
int rsa_max_message_len(mp_int mod)
|
||||
{
|
||||
int num_bits = mp_int_count_bits(mod);
|
||||
int num_bytes = num_bits / CHAR_BIT;
|
||||
|
||||
if(num_bytes < 11)
|
||||
return 0; /* at least eleven bytes are required for padding */
|
||||
else
|
||||
return num_bytes - 11;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ rsa_pkcs1v15_encode(buf, msg_len, buf_len, tag, filler) */
|
||||
|
||||
mp_result rsa_pkcs1v15_encode(unsigned char *buf, int msg_len,
|
||||
int buf_len, int tag, random_f filler)
|
||||
{
|
||||
int pad_len, msg_start;
|
||||
|
||||
/* Make sure there is enough space for the encoded output */
|
||||
if(msg_len > (buf_len - 11))
|
||||
return MP_RANGE;
|
||||
|
||||
msg_start = buf_len - msg_len;
|
||||
pad_len = msg_start - 3;
|
||||
|
||||
/* Move message to top of buffer -- these might overlap, so we rely
|
||||
on the semantics of memmove() here */
|
||||
memmove(buf + msg_start, buf, msg_len);
|
||||
|
||||
/* Set initial bytes as required by the specification */
|
||||
buf[0] = 0x00;
|
||||
buf[1] = (unsigned char)tag;
|
||||
|
||||
/* Fill with random padding. We'll just assume the filler function
|
||||
does the right thing and only writes the requested number of
|
||||
nonzero bytes */
|
||||
(filler)(buf + 2, pad_len);
|
||||
|
||||
/* Write separator between pad and message body */
|
||||
buf[msg_start - 1] = 0x00;
|
||||
|
||||
return MP_OK;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ rsa_pkcs1v15_decode(buf, buf_len, *msg_len) */
|
||||
|
||||
mp_result rsa_pkcs1v15_decode(unsigned char *buf, int buf_len,
|
||||
int tag, int *msg_len)
|
||||
{
|
||||
int pad_len = 0, data_len, data_start, i;
|
||||
|
||||
/* Make sure the buffer is syntactically valid */
|
||||
if(buf_len < 11 || buf[0] != 0x00 || buf[1] != (unsigned char)tag)
|
||||
return MP_UNDEF;
|
||||
|
||||
/* Figure out how many bytes of random padding there are */
|
||||
i = 2;
|
||||
while(buf[i++] != '\0')
|
||||
++pad_len;
|
||||
|
||||
data_start = i;
|
||||
data_len = buf_len - data_start;
|
||||
|
||||
/* Shift the message to the front of the buffer */
|
||||
memmove(buf, buf + data_start, data_len);
|
||||
|
||||
/* Zero out the rest of the buffer */
|
||||
memset(buf + data_len, 0, pad_len + 3);
|
||||
|
||||
*msg_len = data_len;
|
||||
|
||||
return MP_OK;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ s_rsa_transform(msg, exp, mod, out) */
|
||||
|
||||
static mp_result s_rsa_transform(mp_int msg, mp_int exp,
|
||||
mp_int mod, mp_int out)
|
||||
{
|
||||
if(mp_int_compare_zero(msg) < 0 ||
|
||||
mp_int_compare(msg, mod) >= 0)
|
||||
return MP_RANGE;
|
||||
|
||||
return mp_int_exptmod(msg, exp, mod, out);
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* Here there be dragons */
|
91
lib/des/imath/rsamath.h
Executable file
91
lib/des/imath/rsamath.h
Executable file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
Name: rsamath.h
|
||||
Purpose: Implements part of PKCS#1, v. 2.1, June 14, 2002 (RSA Labs)
|
||||
Author: M. J. Fromberger <http://www.dartmouth.edu/~sting/>
|
||||
Info: $Id$
|
||||
|
||||
Copyright (C) 2002 Michael J. Fromberger, All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation files
|
||||
(the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef RSAMATH_H_
|
||||
#define RSAMATH_H_
|
||||
|
||||
#include "imath.h"
|
||||
|
||||
/* Function to fill a buffer with nonzero random bytes */
|
||||
typedef void (*random_f)(unsigned char *, int);
|
||||
|
||||
/* Convert integer to octet string, per PKCS#1 v.2.1 */
|
||||
mp_result rsa_i2osp(mp_int z, unsigned char *out, int len);
|
||||
|
||||
/* Convert octet string to integer, per PKCS#1 v.2.1 */
|
||||
mp_result rsa_os2ip(mp_int z, unsigned char *in, int len);
|
||||
|
||||
/* The following operations assume that you have converted your keys
|
||||
and message data into mp_int values somehow. */
|
||||
|
||||
/* Primitive RSA encryption operation */
|
||||
mp_result rsa_rsaep(mp_int msg, mp_int exp, mp_int mod, mp_int cipher);
|
||||
|
||||
/* Primitive RSA decryption operation */
|
||||
mp_result rsa_rsadp(mp_int cipher, mp_int exp, mp_int mod, mp_int msg);
|
||||
|
||||
/* Primitive RSA signing operation */
|
||||
mp_result rsa_rsasp(mp_int msg, mp_int exp, mp_int mod, mp_int signature);
|
||||
|
||||
/* Primitive RSA verification operation */
|
||||
mp_result rsa_rsavp(mp_int signature, mp_int exp, mp_int mod, mp_int msg);
|
||||
|
||||
/* Compute the maximum length in bytes a message can have using PKCS#1
|
||||
v.1.5 encoding with the given modulus */
|
||||
int rsa_max_message_len(mp_int mod);
|
||||
|
||||
/* Encode a raw message per PKCS#1 v.1.5
|
||||
buf - the buffer containing the message
|
||||
msg_len - the length in bytes of the message
|
||||
buf_len - the size in bytes of the buffer
|
||||
tag - the message tag (nonzero byte)
|
||||
filler - function to generate pseudorandom nonzero padding
|
||||
|
||||
On input, the message is in the first msg_len bytes of the buffer;
|
||||
on output, the contents of the buffer are replaced by the padded
|
||||
message. If there is not enough room, MP_RANGE is returned.
|
||||
*/
|
||||
mp_result rsa_pkcs1v15_encode(unsigned char *buf, int msg_len,
|
||||
int buf_len, int tag, random_f filler);
|
||||
|
||||
/* Decode a PKCS#1 v.1.5 message back to its raw form
|
||||
buf - the buffer containing the encoded message
|
||||
buf_len - the length in bytes of the buffer
|
||||
tag - the expected message tag (nonzero byte)
|
||||
msg_len - on output, receives the length of the message content
|
||||
|
||||
On output, the message is packed into the first msg_len bytes of
|
||||
the buffer, and the rest of the buffer is zeroed. If the buffer is
|
||||
not of the correct form, MP_UNDEF is returned and msg_len is undefined.
|
||||
*/
|
||||
mp_result rsa_pkcs1v15_decode(unsigned char *buf, int buf_len,
|
||||
int tag, int *msg_len);
|
||||
|
||||
|
||||
#endif /* end RSAMATH_H_ */
|
Reference in New Issue
Block a user