added libtomcrypt-0.83

This commit is contained in:
Tom St Denis 2003-03-29 18:19:07 +00:00 committed by Steffen Jaeckel
parent 7d21325daa
commit 90a48a5bec
18 changed files with 964 additions and 272 deletions

3
aes.c
View File

@ -102,8 +102,9 @@ int rijndael_setup(const unsigned char *key, int keylen, int numrounds, symmetri
_ARGCHK(key != NULL);
_ARGCHK(skey != NULL);
if (numrounds == 0)
if (numrounds == 0) {
numrounds = 10 + (2 * ((keylen/8)-2));
}
if (keylen != 16 && keylen != 24 && keylen != 32) {
return CRYPT_INVALID_KEYSIZE;

View File

@ -1,3 +1,11 @@
Mar 29th, 2003
v0.83 -- Optimized the ecc_mulmod, it's faster and takes less heap/stack space
-- Fixed a free memory error in ecc_mulmod and del_point which would try to free NULL
-- Fixed two serious bugs in rsa_decrypt_key and rsa_verify_hash that would allow a trivialy
buffer overflow.
-- Fixed a bug in the hmac testing code if you don't register all the hashes it won't return
errors now.
Mar 15th, 2003
v0.82 -- Manual updated
-- Added MSVC makefile [back, actually its written from scratch to work with NMAKE]

BIN
crypt.pdf

Binary file not shown.

View File

@ -48,7 +48,7 @@
\def\gap{\vspace{0.5ex}}
\makeindex
\begin{document}
\title{A Tiny Crypto Library, \\ LibTomCrypt \\ Version 0.82}
\title{A Tiny Crypto Library, \\ LibTomCrypt \\ Version 0.83}
\author{Tom St Denis \\
Algonquin College \\
\\

View File

@ -1139,7 +1139,7 @@ ecc_tests (void)
}
/* test encrypt_key */
ecc_make_key (&prng, find_prng ("yarrow"), 28, &usera);
ecc_make_key (&prng, find_prng ("yarrow"), 20, &usera);
for (x = 0; x < 32; x++)
buf[0][x] = x;
y = sizeof (buf[1]);
@ -1176,6 +1176,7 @@ ecc_tests (void)
printf ("Error: %s\n", error_to_string (errnum));
exit (-1);
}
printf("Signature size: %lu\n", x);
if (ecc_verify_hash (buf[1], x, buf[0], 16, &stat, &usera)) {
printf ("Error: %s\n", error_to_string (errnum));
exit (-1);
@ -1377,12 +1378,12 @@ register_all_algs (void)
void
kr_display (pk_key * kr)
{
static const char *system[] = { "NON-KEY", "RSA", "DH", "ECC" };
static const char *sys[] = { "NON-KEY", "RSA", "DH", "ECC" };
static const char *type[] = { "PRIVATE", "PUBLIC", "PRIVATE_OPTIMIZED" };
while (kr->system != NON_KEY) {
printf ("CRC [%08lx], System [%10s], Type [%20s], %s, %s, %s\n", kr->ID,
system[kr->system], type[kr->key_type], kr->name, kr->email,
sys[kr->system], type[kr->key_type], kr->name, kr->email,
kr->description);
kr = kr->next;
}

246
ecc.c
View File

@ -235,8 +235,13 @@ static ecc_point *new_point(void)
static void del_point(ecc_point *p)
{
mp_clear_multi(&p->x, &p->y, NULL);
XFREE(p);
/* prevents free'ing null arguments */
if (p == NULL) {
return;
} else {
mp_clear_multi(&p->x, &p->y, NULL);
XFREE(p);
}
}
/* double a point R = 2P, R can be P*/
@ -344,156 +349,161 @@ done:
return res;
}
/* size of sliding window, don't change this! */
#define WINSIZE 4
/* perform R = kG where k == integer and G == ecc_point */
static int ecc_mulmod(mp_int *k, ecc_point *G, ecc_point *R, mp_int *modulus)
{
ecc_point *tG, *M[30];
int i, j, z, res, Q;
mp_digit d;
unsigned char bits[150], m, first;
ecc_point *tG, *M[8];
int i, j, res;
mp_int mu;
if ((USED(k) * MP_DIGIT_BIT) > 256) {
Q = 5;
} else {
Q = 4;
}
if (mp_init(&mu) != MP_OKAY) {
return CRYPT_MEM;
}
mp_digit buf;
int first, bitbuf, bitcpy, bitcnt, mode, digidx;
/* init barrett reduction */
mp_set(&mu, 1);
mp_lshd(&mu, 2 * USED(modulus));
if (mp_div(&mu, modulus, &mu, NULL) != MP_OKAY) {
mp_clear(&mu);
return CRYPT_MEM;
if (mp_init(&mu) != MP_OKAY) {
return CRYPT_MEM;
}
if (mp_reduce_setup(&mu, modulus) != MP_OKAY) {
mp_clear(&mu);
return CRYPT_MEM;
}
/* alloc ram for window temps */
for (i = 0; i < 8; i++) {
M[i] = new_point();
if (M[i] == NULL) {
for (j = 0; j < i; j++) {
del_point(M[j]);
}
mp_clear(&mu);
return CRYPT_MEM;
}
}
/* init M tab (alloc here, calculate below)
This table holds the first 2^Q multiples of the input base point G, that is
M[x] = x * G
Where G is the point and x is a scalar. The implementation is optimized
since M[0] == 0 and M[1] == G so there is no need to waste space for those. In
effect M'[x] == M[x+2] where M'[] is the table we make. If M[0] or M[1] are needed
we handle them with if statements.
*/
for (i = 0; i < ((1<<Q)-2); i++) {
M[i] = new_point();
if (M[i] == NULL) {
for (j = 0; j < i; j++) {
del_point(M[j]);
}
mp_clear(&mu);
return CRYPT_MEM;
}
}
/* get bits of k in groupings of Q
The multiplicand is read in groupings of four bits. This is because the multiplication
routine is a Q-ary left-to-write (see HAC chapter 14, algorithm 14.82).
*/
first = m = (unsigned char)0;
for (z = i = 0; z < (int)USED(k); z++) {
/* grab a digit from the mp_int, these have MP_DIGIT_BIT bits in them */
d = DIGIT(k, z);
for (j = 0; j < (int)MP_DIGIT_BIT; j++) {
/* OR the bits against an accumulator */
first |= (d&1)<<(unsigned)(m++);
/* if the bit count is Q then we have a Q-bit word ready */
if (m == (unsigned char)Q) {
/* store the four bit word and reset counters */
bits[i++] = first;
first = m = (unsigned char)0;
}
/* shift the digit down to extract the next bit */
d >>= 1;
}
}
/* residue of multiplicand [if any] */
if (m) {
bits[i++] = first;
}
/* make a copy of G incase R==G */
tG = new_point();
if (tG == NULL) { goto error; }
if (tG == NULL) { goto error; }
/* skip leading digits which are zero */
--i; while (i != 0 && bits[i] == (unsigned char)0) { --i; }
/* if the multiplicand has no non-zero 4-bit words its invalid. */
if (i == 0) {
res = CRYPT_INVALID_ARG;
goto done;
}
/* now calc the M tab, note that there are only 2^Q - 2 spots, the normal M[0] is a no-op, and M[1] is the input
point (saves ram)
*/
/* M[0] now is 2*G */
/* calc the M tab, which holds kG for k==8..15 */
/* M[0] == 8G */
if (dbl_point(G, M[0], modulus, &mu) != CRYPT_OK) { goto error; }
for (j = 1; j < ((1<<Q)-2); j++) {
if (add_point(M[j-1], G, M[j], modulus, &mu) != CRYPT_OK) { goto error; }
if (dbl_point(M[0], M[0], modulus, &mu) != CRYPT_OK) { goto error; }
if (dbl_point(M[0], M[0], modulus, &mu) != CRYPT_OK) { goto error; }
/* now find (8+k)G for k=1..7 */
for (j = 9; j < 16; j++) {
if (add_point(M[j-9], G, M[j-8], modulus, &mu) != CRYPT_OK) { goto error; }
}
/* tG = G */
if (mp_copy(&G->x, &tG->x) != MP_OKAY) { goto error; }
if (mp_copy(&G->y, &tG->y) != MP_OKAY) { goto error; }
if (mp_copy(&G->x, &tG->x) != MP_OKAY) { goto error; }
if (mp_copy(&G->y, &tG->y) != MP_OKAY) { goto error; }
/* set result M[bits[i]] */
if (bits[i] == (unsigned char)1) {
if (mp_copy(&G->x, &R->x) != MP_OKAY) { goto error; }
if (mp_copy(&G->y, &R->y) != MP_OKAY) { goto error; }
} else if (bits[i] >= (unsigned char)2) {
if (mp_copy(&M[(int)bits[i]-2]->x, &R->x) != MP_OKAY) { goto error; }
if (mp_copy(&M[(int)bits[i]-2]->y, &R->y) != MP_OKAY) { goto error; }
}
/* setup sliding window */
mode = 0;
bitcnt = 1;
buf = 0;
digidx = k->used - 1;
bitcpy = bitbuf = 0;
first = 1;
while (--i >= 0) {
/* double */
for (j = 0; j < Q; j++) {
if (dbl_point(R, R, modulus, &mu) != CRYPT_OK) { goto error; }
/* perform ops */
for (;;) {
/* grab next digit as required */
if (--bitcnt == 0) {
if (digidx == -1) {
break;
}
/* now based on the value of bits[i] we do ops */
if (bits[i] == (unsigned char)0) {
/* nop */
} else if (bits[i] == (unsigned char)1) {
/* add base point */
if (add_point(R, tG, R, modulus, &mu) != CRYPT_OK) { goto error; }
buf = k->dp[digidx--];
bitcnt = (int) DIGIT_BIT;
}
/* grab the next msb from the multiplicand */
i = (buf >> (DIGIT_BIT - 1)) & 1;
buf <<= 1;
/* skip leading zero bits */
if (mode == 0 && i == 0)
continue;
/* if the bit is zero and mode == 1 then we double */
if (mode == 1 && i == 0) {
if (dbl_point(R, R, modulus, &mu) != CRYPT_OK) { goto error; }
continue;
}
/* else we add it to the window */
bitbuf |= (i << (WINSIZE - ++bitcpy));
mode = 2;
if (bitcpy == WINSIZE) {
/* if this is the first window we do a simple copy */
if (first == 1) {
/* R = kG [k = first window] */
if (mp_copy(&M[bitbuf-8]->x, &R->x) != MP_OKAY) { goto error; }
if (mp_copy(&M[bitbuf-8]->y, &R->y) != MP_OKAY) { goto error; }
first = 0;
} else {
/* other case */
if (add_point(R, M[(int)bits[i] - 2], R, modulus, &mu) != CRYPT_OK) { goto error; }
/* normal window */
/* ok window is filled so double as required and add */
/* double first */
for (j = 0; j < WINSIZE; j++) {
if (dbl_point(R, R, modulus, &mu) != CRYPT_OK) { goto error; }
}
/* then add, bitbuf will be 1..15 [1..2^WINSIZE] guaranteed */
if (bitbuf == 1) {
if (add_point(R, tG, R, modulus, &mu) != CRYPT_OK) { goto error; }
} else {
if (add_point(R, M[bitbuf-8], R, modulus, &mu) != CRYPT_OK) { goto error; }
}
}
}
/* empty window and reset */
bitcpy = bitbuf = 0;
mode = 1;
}
}
/* if bits remain then double/add */
if (mode == 2 && bitcpy > 0) {
/* double then add */
for (j = 0; j < bitcpy; j++) {
/* only double if we have had at least one add first */
if (first == 0) {
if (dbl_point(R, R, modulus, &mu) != CRYPT_OK) { goto error; }
}
bitbuf <<= 1;
if ((bitbuf & (1 << WINSIZE)) != 0) {
if (first == 1){
/* first add, so copy */
if (mp_copy(&tG->x, &R->x) != MP_OKAY) { goto error; }
if (mp_copy(&tG->y, &R->y) != MP_OKAY) { goto error; }
first = 0;
} else {
/* then add */
if (add_point(R, tG, R, modulus, &mu) != CRYPT_OK) { goto error; }
}
}
}
}
res = CRYPT_OK;
goto done;
error:
res = CRYPT_MEM;
done:
del_point(tG);
for (i = 0; i < ((1<<Q)-2); i++) {
for (i = 0; i < 8; i++) {
del_point(M[i]);
}
mp_clear(&mu);
#ifdef CLEAN_STACK
zeromem(bits, sizeof(bits));
#endif
return res;
}
#undef WINSIZE
int ecc_test(void)
{
mp_int modulus, order;

10
hmac.c
View File

@ -456,9 +456,11 @@ Key First"
unsigned long outlen;
int err;
int failed=0;
int tested=0,failed=0;
for(i=0; i < (int)(sizeof(cases) / sizeof(cases[0])); i++) {
int hash = find_hash(cases[i].algo);
if (hash == -1) continue;
++tested;
outlen = sizeof(digest);
if((err = hmac_memory(hash, cases[i].key, cases[i].keylen, cases[i].data, cases[i].datalen, digest, &outlen)) != CRYPT_OK) {
#if 0
@ -490,9 +492,11 @@ Key First"
if (failed != 0) {
return CRYPT_FAIL_TESTVECTOR;
} else if (tested == 0) {
return CRYPT_NOP;
} else {
return CRYPT_OK;
}
return CRYPT_OK;
}
#endif

View File

@ -137,7 +137,7 @@ pk_key *kr_find_name(pk_key *pk, const char *name)
}
int kr_add(pk_key *pk, int key_type, int system, const unsigned char *name,
int kr_add(pk_key *pk, int key_type, int sys, const unsigned char *name,
const unsigned char *email, const unsigned char *description, const _pk_key *key)
{
_ARGCHK(pk != NULL);
@ -151,7 +151,7 @@ int kr_add(pk_key *pk, int key_type, int system, const unsigned char *name,
return CRYPT_PK_INVALID_TYPE;
}
if (system != RSA_KEY && system != DH_KEY && system != ECC_KEY) {
if (sys != RSA_KEY && sys != DH_KEY && sys != ECC_KEY) {
return CRYPT_PK_INVALID_SYSTEM;
}
@ -177,7 +177,7 @@ int kr_add(pk_key *pk, int key_type, int system, const unsigned char *name,
/* now add this new data to this ring spot */
pk->key_type = key_type;
pk->system = system;
pk->system = sys;
strncpy((char *)pk->name, (char *)name, sizeof(pk->name)-1);
strncpy((char *)pk->email, (char *)email, sizeof(pk->email)-1);
strncpy((char *)pk->description, (char *)description, sizeof(pk->description)-1);
@ -187,7 +187,7 @@ int kr_add(pk_key *pk, int key_type, int system, const unsigned char *name,
zeromem(&(pk->key), sizeof(pk->key));
/* copy the key */
switch (system) {
switch (sys) {
case RSA_KEY:
memcpy(&(pk->key.rsa), &(key->rsa), sizeof(key->rsa));
break;
@ -366,7 +366,7 @@ int kr_export(pk_key *pk, unsigned long ID, int key_type, unsigned char *out, un
int kr_import(pk_key *pk, const unsigned char *in, unsigned long inlen)
{
_pk_key key;
int system, key_type, err;
int sys, key_type, err;
unsigned long ID;
_ARGCHK(pk != NULL);
@ -380,7 +380,7 @@ int kr_import(pk_key *pk, const unsigned char *in, unsigned long inlen)
return CRYPT_INVALID_PACKET;
}
key_type = in[4]; /* get type */
system = in[5]; /* get system */
sys = in[5]; /* get system */
LOAD32L(ID,in+6); /* the ID */
if (ID != kr_crc(in+10, in+10+MAXLEN, in+10+MAXLEN+MAXLEN)) {
@ -392,7 +392,7 @@ int kr_import(pk_key *pk, const unsigned char *in, unsigned long inlen)
/* size of remaining packet */
inlen -= 10 + 3*MAXLEN;
switch (system) {
switch (sys) {
case RSA_KEY:
if ((err = rsa_import(in+10+3*MAXLEN, inlen, &(key.rsa))) != CRYPT_OK) {
return err;
@ -409,7 +409,7 @@ int kr_import(pk_key *pk, const unsigned char *in, unsigned long inlen)
}
break;
}
return kr_add(pk, key_type, system,
return kr_add(pk, key_type, sys,
in+10, /* the name */
in+10+MAXLEN, /* email address */
in+10+MAXLEN+MAXLEN, /* description */
@ -509,7 +509,7 @@ done:
}
int kr_make_key(pk_key *pk, prng_state *prng, int wprng,
int system, int keysize, const unsigned char *name,
int sys, int keysize, const unsigned char *name,
const unsigned char *email, const unsigned char *description)
{
_pk_key key;
@ -527,7 +527,7 @@ int kr_make_key(pk_key *pk, prng_state *prng, int wprng,
/* make the key first */
zeromem(&key, sizeof(key));
switch (system) {
switch (sys) {
case RSA_KEY:
if ((err = rsa_make_key(prng, wprng, keysize, 65537, &(key.rsa))) != CRYPT_OK) {
return err;
@ -551,7 +551,7 @@ int kr_make_key(pk_key *pk, prng_state *prng, int wprng,
}
/* now add the key */
if ((err = kr_add(pk, key_type, system, name, email, description, &key)) != CRYPT_OK) {
if ((err = kr_add(pk, key_type, sys, name, email, description, &key)) != CRYPT_OK) {
return err;
}

View File

@ -9,7 +9,7 @@
# a build. This is easy to remedy though, for those that have problems.
# The version
VERSION=0.82
VERSION=0.83
#ch1-01-1
# Compiler and Linker Names
@ -23,7 +23,7 @@ ARFLAGS=r
#ch1-01-3
# Compilation flags. Note the += does not write over the user's CFLAGS!
CFLAGS += -c -I./ -Wall -Wsign-compare -W -Wno-unused -Werror
CFLAGS += -c -I./ -Wall -Wsign-compare -W -Wno-unused -Wshadow -Werror
# optimize for SPEED
#CFLAGS += -O3 -funroll-loops

View File

@ -2,7 +2,7 @@
#
#Tom St Denis
CFLAGS = /I. /Ogityb2 /Gs /DWIN32 /W3
CFLAGS = /I. /Ogiyb2t /Gs /DWIN32 /W3
default: library

814
mpi.c

File diff suppressed because it is too large Load Diff

View File

@ -16,8 +16,8 @@ extern "C" {
#endif
/* version */
#define CRYPT 0x0082
#define SCRYPT "0.82"
#define CRYPT 0x0083
#define SCRYPT "0.83"
/* max size of either a cipher/hash block or symmetric key [largest of the two] */
#define MAXBLOCKSIZE 128
@ -27,6 +27,7 @@ extern "C" {
enum {
CRYPT_OK=0, /* Result OK */
CRYPT_ERROR, /* Generic Error */
CRYPT_NOP, /* Not a failure but no operation was performed */
CRYPT_INVALID_KEYSIZE, /* Invalid key size given */
CRYPT_INVALID_ROUNDS, /* Invalid number of rounds */

View File

@ -42,13 +42,13 @@ extern unsigned long kr_crc(const unsigned char *name, const unsigned char *emai
extern pk_key *kr_find(pk_key *pk, unsigned long ID);
extern pk_key *kr_find_name(pk_key *pk, const char *name);
extern int kr_add(pk_key *pk, int key_type, int system, const unsigned char *name,
extern int kr_add(pk_key *pk, int key_type, int sys, const unsigned char *name,
const unsigned char *email, const unsigned char *description, const _pk_key *key);
extern int kr_del(pk_key **_pk, unsigned long ID);
extern int kr_clear(pk_key **pk);
extern int kr_make_key(pk_key *pk, prng_state *prng, int wprng,
int system, int keysize, const unsigned char *name,
int sys, int keysize, const unsigned char *name,
const unsigned char *email, const unsigned char *description);
extern int kr_export(pk_key *pk, unsigned long ID, int key_type, unsigned char *out, unsigned long *outlen);

View File

@ -85,7 +85,7 @@ extern char *crypt_error;
#ifdef ENDIAN_32BITWORD
#define STORE32L(x, y) \
{ unsigned long t = (x); memcpy(y, &t, 4); }
{ unsigned long __t = (x); memcpy(y, &__t, 4); }
#define LOAD32L(x, y) \
memcpy(&(x), y, 4);
@ -105,13 +105,13 @@ extern char *crypt_error;
#else /* 64-bit words then */
#define STORE32L(x, y) \
{ unsigned long t = (x); memcpy(y, &t, 4); }
{ unsigned long __t = (x); memcpy(y, &__t, 4); }
#define LOAD32L(x, y) \
{ memcpy(&(x), y, 4); x &= 0xFFFFFFFF; }
#define STORE64L(x, y) \
{ ulong64 t = (x); memcpy(y, &t, 8); }
{ ulong64 __t = (x); memcpy(y, &__t, 8); }
#define LOAD64L(x, y) \
{ memcpy(&(x), y, 8); }
@ -146,7 +146,7 @@ extern char *crypt_error;
#ifdef ENDIAN_32BITWORD
#define STORE32H(x, y) \
{ unsigned long t = (x); memcpy(y, &t, 4); }
{ unsigned long __t = (x); memcpy(y, &__t, 4); }
#define LOAD32H(x, y) \
memcpy(&(x), y, 4);
@ -166,13 +166,13 @@ extern char *crypt_error;
#else /* 64-bit words then */
#define STORE32H(x, y) \
{ unsigned long t = (x); memcpy(y, &t, 4); }
{ unsigned long __t = (x); memcpy(y, &__t, 4); }
#define LOAD32H(x, y) \
{ memcpy(&(x), y, 4); x &= 0xFFFFFFFF; }
#define STORE64H(x, y) \
{ ulong64 t = (x); memcpy(y, &t, 8); }
{ ulong64 __t = (x); memcpy(y, &__t, 8); }
#define LOAD64H(x, y) \
{ memcpy(&(x), y, 8); }

View File

@ -104,16 +104,12 @@ int rsa_decrypt_key(const unsigned char *in, unsigned long inlen,
}
y += 4;
/* read it in */
for (x = 0; x < rsa_size; x++, y++) {
rsa_in[x] = in[y];
}
/* decrypt it */
x = (unsigned long)sizeof(rsa_out);
if ((err = rsa_exptmod(rsa_in, rsa_size, rsa_out, &x, PK_PRIVATE, key)) != CRYPT_OK) {
if ((err = rsa_exptmod(in+y, rsa_size, rsa_out, &x, PK_PRIVATE, key)) != CRYPT_OK) {
return err;
}
y += rsa_size;
/* depad it */
z = (unsigned long)sizeof(sym_key);
@ -240,16 +236,12 @@ int rsa_verify_hash(const unsigned char *sig, unsigned long siglen,
}
y += 4;
/* load the signature */
for (x = 0; x < rsa_size; x++, y++) {
rsa_in[x] = sig[y];
}
/* exptmod it */
x = (unsigned long)sizeof(rsa_in);
if ((err = rsa_exptmod(rsa_in, rsa_size, rsa_out, &x, PK_PUBLIC, key)) != CRYPT_OK) {
x = (unsigned long)sizeof(rsa_out);
if ((err = rsa_exptmod(sig+y, rsa_size, rsa_out, &x, PK_PUBLIC, key)) != CRYPT_OK) {
return err;
}
y += rsa_size;
/* depad it */
z = (unsigned long)sizeof(rsa_in);

View File

@ -5,6 +5,7 @@ static const char *err_2_str[] =
{
"CRYPT_OK",
"CRYPT_ERROR",
"Non-fatal 'no-operation' requested.",
"Invalid keysize for block cipher.",
"Invalid number of rounds for block cipher.",

View File

@ -10,10 +10,10 @@
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tomstdenis@iahu.ca, http://libtommath.iahu.ca
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/
#include "mycrypt.h"
#include <mycrypt.h>
#ifndef BN_H_
#define BN_H_
@ -30,8 +30,16 @@
#ifdef __cplusplus
extern "C" {
#endif
/* C++ compilers don't like assigning void * to mp_digit * */
#define OPT_CAST (mp_digit *)
#else
/* C on the other hand dosen't care */
#define OPT_CAST
#endif
/* some default configurations.
*
@ -118,6 +126,12 @@ void mp_exch(mp_int *a, mp_int *b);
/* shrink ram required for a bignum */
int mp_shrink(mp_int *a);
/* grow an int to a given size */
int mp_grow(mp_int *a, int size);
/* init to a given number of digits */
int mp_init_size(mp_int *a, int size);
/* ---> Basic Manipulations <--- */
#define mp_iszero(a) (((a)->used == 0) ? 1 : 0)
@ -133,12 +147,6 @@ void mp_set(mp_int *a, mp_digit b);
/* set a 32-bit const */
int mp_set_int(mp_int *a, unsigned long b);
/* grow an int to a given size */
int mp_grow(mp_int *a, int size);
/* init to a given number of digits */
int mp_init_size(mp_int *a, int size);
/* copy, b = a */
int mp_copy(mp_int *a, mp_int *b);
@ -204,7 +212,6 @@ int mp_cmp_mag(mp_int *a, mp_int *b);
/* c = a + b */
int mp_add(mp_int *a, mp_int *b, mp_int *c);
/* c = a - b */
int mp_sub(mp_int *a, mp_int *b, mp_int *c);
@ -299,9 +306,52 @@ int mp_montgomery_calc_normalization(mp_int *a, mp_int *b);
/* computes xR^-1 == x (mod N) via Montgomery Reduction */
int mp_montgomery_reduce(mp_int *a, mp_int *m, mp_digit mp);
/* returns 1 if a is a valid DR modulus */
int mp_dr_is_modulus(mp_int *a);
/* sets the value of "d" required for mp_dr_reduce */
void mp_dr_setup(mp_int *a, mp_digit *d);
/* reduces a modulo b using the Diminished Radix method */
int mp_dr_reduce(mp_int *a, mp_int *b, mp_digit mp);
/* d = a^b (mod c) */
int mp_exptmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
/* ---> Primes <--- */
#define PRIME_SIZE 256 /* number of primes */
/* table of first 256 primes */
extern const mp_digit __prime_tab[];
/* result=1 if a is divisible by one of the first 256 primes */
int mp_prime_is_divisible(mp_int *a, int *result);
/* performs one Fermat test of "a" using base "b".
* Sets result to 0 if composite or 1 if probable prime
*/
int mp_prime_fermat(mp_int *a, mp_int *b, int *result);
/* performs one Miller-Rabin test of "a" using base "b".
* Sets result to 0 if composite or 1 if probable prime
*/
int mp_prime_miller_rabin(mp_int *a, mp_int *b, int *result);
/* performs t rounds of Miller-Rabin on "a" using the first
* t prime bases. Also performs an initial sieve of trial
* division. Determines if "a" is prime with probability
* of error no more than (1/4)^t.
*
* Sets result to 1 if probably prime, 0 otherwise
*/
int mp_prime_is_prime(mp_int *a, int t, int *result);
/* finds the next prime after the number "a" using "t" trials
* of Miller-Rabin.
*/
int mp_prime_next_prime(mp_int *a, int t);
/* ---> radix conversion <--- */
int mp_count_bits(mp_int *a);
@ -343,7 +393,7 @@ int mp_karatsuba_mul(mp_int *a, mp_int *b, mp_int *c);
int mp_karatsuba_sqr(mp_int *a, mp_int *b);
int fast_mp_invmod(mp_int *a, mp_int *b, mp_int *c);
int fast_mp_montgomery_reduce(mp_int *a, mp_int *m, mp_digit mp);
int mp_exptmod_fast(mp_int *G, mp_int *X, mp_int *P, mp_int *Y);
int mp_exptmod_fast(mp_int *G, mp_int *X, mp_int *P, mp_int *Y, int mode);
void bn_reverse(unsigned char *s, int len);
#ifdef __cplusplus

View File

@ -136,6 +136,10 @@ unsigned long yarrow_read(unsigned char *buf, unsigned long len, prng_state *prn
_ARGCHK(buf != NULL);
_ARGCHK(prng != NULL);
/* put buf in predictable state first */
zeromem(buf, len);
/* now randomize it */
if (ctr_encrypt(buf, buf, len, &prng->yarrow.ctr) != CRYPT_OK) {
return 0;
}