added libtomcrypt-0.84

This commit is contained in:
Tom St Denis 2003-06-01 18:55:11 +00:00 committed by Steffen Jaeckel
parent 90a48a5bec
commit d6071c6267
41 changed files with 7688 additions and 6574 deletions

4
aes.c
View File

@ -327,6 +327,9 @@ void rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_
int rijndael_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
int errno;
static const struct {
int keylen;
@ -377,6 +380,7 @@ int rijndael_test(void)
}
}
return CRYPT_OK;
#endif
}
int rijndael_keysize(int *desired_keysize)

55
ampi.c
View File

@ -1,55 +0,0 @@
/* Code submitted by Svante Seleborg, cleaned up by Tom St Denis */
#include "mycrypt.h"
#include <stdarg.h>
#ifdef MPI
mp_err mp_init_multi(mp_int *mp, ...)
{
mp_err res = MP_OKAY; /* Assume ok until proven otherwise */
int n = 0; /* Number of ok inits */
mp_int* cur_arg = mp;
va_list args;
va_start(args, mp); /* init args to next argument from caller */
while (cur_arg != NULL) {
if (mp_init(cur_arg) != MP_OKAY) {
/* Oops - error! Back-track and mp_clear what we already
succeeded in init-ing, then return error.
*/
va_list clean_args;
cur_arg = mp;
va_start(clean_args, mp);
while (n--) {
mp_clear(cur_arg);
cur_arg = va_arg(clean_args, mp_int*);
}
va_end(clean_args);
res = MP_MEM;
break;
}
n++;
cur_arg = va_arg(args, mp_int*);
}
va_end(args);
return res; /* Assumed ok, if error flagged above. */
}
/*
Clear all arguments given, ended by a NULL marker.
*/
void mp_clear_multi(mp_int *mp, ...)
{
mp_int* next_mp = mp;
va_list args;
va_start(args, mp);
while (next_mp != NULL) {
mp_clear(next_mp);
next_mp = va_arg(args, mp_int*);
}
va_end(args);
}
#endif

View File

@ -436,6 +436,9 @@ void blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_
int blowfish_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
int err;
symmetric_key key;
static const struct {
@ -476,6 +479,7 @@ int blowfish_test(void)
}
}
return CRYPT_OK;
#endif
}
int blowfish_keysize(int *desired_keysize)

View File

@ -552,6 +552,9 @@ void cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key
int cast5_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
int keylen;
unsigned char key[16];
@ -590,6 +593,7 @@ int cast5_test(void)
}
return CRYPT_OK;
#endif
}
int cast5_keysize(int *desired_keysize)

11
changes
View File

@ -1,3 +1,14 @@
Jun 1st, 2003
v0.84 -- Removed a 4KB buffer from rsa_decrypt_key that wasn't being used no more
-- Fixed another potential buffer problem. Not an overflow but could cause the
PK import routines to read past the end of the buffer.
-- Optimized the ECC mulmod more by removing a if condition that will always be false
-- Optimized prime.c to not include a 2nd prime table, removed code from is_prime calls prime
test from LibTomMath now
-- Added LTC_TEST define which when defined will enable the test vector routines [see mycrypt_custom.h]
-- Removed ampi.o from the depends cuz it ain't no not working in *nix with it [routines are in mpi.c now].
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

View File

@ -24,6 +24,7 @@
"SMALL_CODE,Use small code where possible (slower code),y",
"NO_FILE,Avoid file I/O calls,n",
"CLEAN_STACK,Clean the stack within functions,n",
"LTC_TEST,Include Test Vector Routines,y",
"BLOWFISH,Include Blowfish block cipher,y",
"RC2,Include RC2 block cipher,y",
@ -144,7 +145,7 @@ for (@settings) {
# output objects
print OUT "\ndefault: library\n\n";
print OUT "OBJECTS = keyring.o gf.o mem.o sprng.o ecc.o base64.o dh.o rsa.o bits.o yarrow.o cfb.o ofb.o ecb.o ctr.o cbc.o hash.o tiger.o sha1.o md5.o md4.o md2.o sha256.o sha512.o xtea.o aes.o serpent.o des.o safer_tab.o safer.o safer+.o rc4.o rc2.o rc6.o rc5.o cast5.o noekeon.o blowfish.o crypt.o ampi.o mpi.o prime.o twofish.o packet.o hmac.o strings.o\n\n";
print OUT "OBJECTS = keyring.o gf.o mem.o sprng.o ecc.o base64.o dh.o rsa.o bits.o yarrow.o cfb.o ofb.o ecb.o ctr.o cbc.o hash.o tiger.o sha1.o md5.o md4.o md2.o sha256.o sha512.o xtea.o aes.o serpent.o des.o safer_tab.o safer.o safer+.o rc4.o rc2.o rc6.o rc5.o cast5.o noekeon.o blowfish.o crypt.o mpi.o prime.o twofish.o packet.o hmac.o strings.o\n\n";
# some depends
print OUT "rsa.o: rsa_sys.c\ndh.o: dh_sys.c\necc.o: ecc_sys.c\n\n";

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.83}
\title{A Tiny Crypto Library, \\ LibTomCrypt \\ Version 0.84}
\author{Tom St Denis \\
Algonquin College \\
\\
@ -64,8 +64,8 @@ Canada
\newpage
\tableofcontents
\chapter{Introduction}
\section{What is the Libtomcrypt?}
Libtomcrypt is a portable ANSI C cryptographic library that supports symmetric ciphers, one-way hashes,
\section{What is the LibTomCrypt?}
LibTomCrypt is a portable ANSI C cryptographic library that supports symmetric ciphers, one-way hashes,
pseudo-random number generators, public key cryptography (via RSA,DH or ECC/DH) and a plethora of support
routines. It is designed to compile out of the box with the GNU C Compiler (GCC) version 2.95.3 (and higher)
and with MSVC version 6 in win32.
@ -932,12 +932,12 @@ int hash_filehandle(int hash, FILE *in,
unsigned char *dst, unsigned long *outlen);
\end{verbatim}
All three functions return {\bf CRYPT\_OK} on success, otherwise they return an error code. The ``hash'' parameter is
the location in the descriptor table of the hash. The ``*outlen'' variable is used to keep track of the output size. You
The ``hash'' parameter is the location in the descriptor table of the hash (\textit{e.g. the return of find\_hash()}).
The ``*outlen'' variable is used to keep track of the output size. You
must set it to the size of your output buffer before calling the functions. When they complete succesfully they store
the length of the message digest back in it. The functions are otherwise straightforward. The ``hash\_filehandle''
function assumes that ``in'' is an file handle opened in binary mode. It will not reset the file position after
hashing the content.
function assumes that ``in'' is an file handle opened in binary mode. It will hash to the end of file and not reset
the file position when finished.
To perform the above hash with md5 the following code could be used:
\begin{small}
@ -993,7 +993,7 @@ int unregister_hash(const struct _hash_descriptor *hash);
\end{verbatim}
\subsection{Notice}
It is highly recommended that you not use the MD4 or MD5 hashes for the purposes of digital signatures or authentication codes.
It is highly recommended that you \textbf{not} use the MD4 or MD5 hashes for the purposes of digital signatures or authentication codes.
These hashes are provided for completeness and they still can be used for the purposes of password hashing or one-way accumulators
(e.g. Yarrow).
@ -1039,16 +1039,16 @@ int hmac_memory(int hash, const unsigned char *key, unsigned long keylen,
unsigned char *dst, unsigned long *dstlen);
\end{verbatim}
This will produce an HMAC code for the array of octets in ``data'' of length ``len''. The index into the hash descriptor
table must be provided in ``hash'' it uses the key from ``key'' with a key length of ``keylen''.
The result is stored in the array of octets ``dst'' and the length in ``dstlen''. Similarly for files there is the
following function:
table must be provided in ``hash''. It uses the key from ``key'' with a key length of ``keylen''.
The result is stored in the array of octets ``dst'' and the length in ``dstlen''. The value of ``dstlen'' must be set
to the size of the destination buffer before calling this function. Similarly for files there is the following function:
\begin{verbatim}
int hmac_file(int hash, const char *fname, const unsigned char *key,
unsigned long keylen,
unsigned char *dst, unsigned long *dstlen);
\end{verbatim}
``hash'' is the index into the hash descriptor table of the hash you want to use. ``fname'' is the filename to process. ``key''
is the array of octets to use as the key. ``keylen'' is the length of the key. ``dst'' is the array of octets where the
``hash'' is the index into the hash descriptor table of the hash you want to use. ``fname'' is the filename to process.
``key'' is the array of octets to use as the key of length ``keylen''. ``dst'' is the array of octets where the
result should be stored.
To test if the HMAC code is working there is the following function:
@ -1378,7 +1378,7 @@ int rsa_make_key(prng_state *prng,
Where ``wprng'' is the index into the PRNG descriptor array. ``size'' is the size in bytes of the RSA modulus desired.
``e'' is the encryption exponent desired, typical values are 3, 17, 257 and 65537. I suggest you stick with 65537 since its big
enough to prevent trivial math attacks and not super slow. ``key'' is where the key is placed. All keys must be at
least 128 bytes and no more than 512 bytes in size (that is from 1024 to 4096 bits).
least 128 bytes and no more than 512 bytes in size (\textit{that is from 1024 to 4096 bits}).
Note that the ``rsa\_make\_key()'' function allocates memory at runtime when you make the key. Make sure to call
``rsa\_free()'' (see below) when you are finished with the key. If ``rsa\_make\_key()'' fails it will automatically
@ -1408,22 +1408,21 @@ recipient who can RSA decrypt it and symmetrically decrypt the message.
int rsa_encrypt_key(const unsigned char *inkey, unsigned long inlen,
unsigned char *outkey, unsigned long *outlen,
prng_state *prng, int wprng, rsa_key *key);
\end{verbatim}
This function is used to RSA encrypt a symmetric to share with another user. The symmetric key and its length are
passed as ``inkey'' and ``inlen'' respectively. The symmetric key is limited to a range of 8 to 32 bytes
(\textit{64 to 256 bits}). The RSA encrypted packet is stored in ``outkey'' and will be of length ``outlen'' bytes. The
value of ``outlen'' must be originally set to the size of the output buffer.
\begin{verbatim}
int rsa_decrypt_key(const unsigned char *in, unsigned long inlen,
unsigned char *outkey, unsigned long *keylen,
rsa_key *key);
\end{verbatim}
The ``rsa\_encrypt\_key()'' function accepts a symmetric key (limited to 32 bytes) as input in ``inkey''. ``inlen''
is the size of the input key in bytes. The function will then ``rsa\_pad()'' the key and encrypt it using the RSA
algorithm. It will store the result in ``outkey'' along with the length in ``outlen''.
The ``rsa\_decrypt\_key()'' function performs the opposite. The ``in'' variable is where the RSA packet of length
``inlen'' goes and it will store the original symmetric key in the ``outkey'' variable along with its length in
``keylen''.
Similarly to sign or verify a hash of a message the following two messages are provided. The idea is to hash your
message then use these functions to RSA sign the hash.
This function will decrypt an RSA packet to retrieve the original symmetric key encrypted with rsa\_encrypt\_key().
Similarly to sign or verify a hash of a message the following two messages are provided. The idea is to hash your message
then use these functions to RSA sign the hash.
\begin{verbatim}
int rsa_sign_hash(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen,

View File

@ -14,21 +14,21 @@ int errnum;
int
null_setup (const unsigned char *key, int keylen, int num_rounds,
symmetric_key * skey)
symmetric_key * skey)
{
return CRYPT_OK;
}
void
null_ecb_encrypt (const unsigned char *pt, unsigned char *ct,
symmetric_key * key)
symmetric_key * key)
{
memcpy (ct, pt, 8);
}
void
null_ecb_decrypt (const unsigned char *ct, unsigned char *pt,
symmetric_key * key)
symmetric_key * key)
{
memcpy (pt, ct, 8);
}
@ -156,7 +156,7 @@ cbc_tests (void)
/* now lets start a cbc session */
if ((errnum =
cbc_start (find_cipher ("blowfish"), IV, key, 16, 0,
&cbc)) != CRYPT_OK) {
&cbc)) != CRYPT_OK) {
printf ("CBC Setup: %s\n", error_to_string (errnum));
exit (-1);
}
@ -179,7 +179,7 @@ cbc_tests (void)
/* now lets start a cbc session */
if ((errnum =
cbc_start (find_cipher ("blowfish"), IV, key, 16, 0,
&cbc)) != CRYPT_OK) {
&cbc)) != CRYPT_OK) {
printf ("CBC Setup: %s\n", error_to_string (errnum));
exit (-1);
}
@ -201,12 +201,12 @@ cbc_tests (void)
/* lets actually check the bytes */
memset (IV, 0, 8);
IV[0] = 0xFF; /* IV = FF 00 00 00 00 00 00 00 */
IV[0] = 0xFF; /* IV = FF 00 00 00 00 00 00 00 */
memset (blk, 0, 32);
blk[8] = 0xFF; /* BLK = 00 00 00 00 00 00 00 00 FF 00 00 00 00 00 00 00 */
blk[8] = 0xFF; /* BLK = 00 00 00 00 00 00 00 00 FF 00 00 00 00 00 00 00 */
cbc_start (find_cipher ("memcpy()"), IV, key, 8, 0, &cbc);
cbc_encrypt (blk, ct, &cbc); /* expect: FF 00 00 00 00 00 00 00 */
cbc_encrypt (blk + 8, ct + 8, &cbc); /* expect: 00 00 00 00 00 00 00 00 */
cbc_encrypt (blk, ct, &cbc); /* expect: FF 00 00 00 00 00 00 00 */
cbc_encrypt (blk + 8, ct + 8, &cbc); /* expect: 00 00 00 00 00 00 00 00 */
if (memcmp (ct, test, 16)) {
printf ("CBC failed logical testing.\n");
for (x = 0; x < 16; x++)
@ -309,7 +309,7 @@ cfb_tests (void)
/* now lets start a cfb session */
if ((errnum =
cfb_start (find_cipher ("blowfish"), IV, key, 16, 0,
&cfb)) != CRYPT_OK) {
&cfb)) != CRYPT_OK) {
printf ("CFB setup: %s\n", error_to_string (errnum));
exit (-1);
}
@ -332,7 +332,7 @@ cfb_tests (void)
/* now lets start a cfb session */
if ((errnum =
cfb_start (find_cipher ("blowfish"), IV, key, 16, 0,
&cfb)) != CRYPT_OK) {
&cfb)) != CRYPT_OK) {
printf ("CFB Setup: %s\n", error_to_string (errnum));
exit (-1);
}
@ -380,7 +380,7 @@ ctr_tests (void)
/* now lets start a ctr session */
if ((errnum =
ctr_start (find_cipher ("xtea"), count, key, 16, 0,
&ctr)) != CRYPT_OK) {
&ctr)) != CRYPT_OK) {
printf ("CTR Setup: %s\n", error_to_string (errnum));
exit (-1);
}
@ -403,7 +403,7 @@ ctr_tests (void)
/* now lets start a cbc session */
if ((errnum =
ctr_start (find_cipher ("xtea"), count, key, 16, 0,
&ctr)) != CRYPT_OK) {
&ctr)) != CRYPT_OK) {
printf ("CTR Setup: %s\n", error_to_string (errnum));
exit (-1);
}
@ -426,12 +426,12 @@ ctr_tests (void)
/* lets actually check the bytes */
memset (count, 0, 8);
count[0] = 0xFF; /* IV = FF 00 00 00 00 00 00 00 */
count[0] = 0xFF; /* IV = FF 00 00 00 00 00 00 00 */
memset (blk, 0, 32);
blk[9] = 2; /* BLK = 00 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 */
blk[9] = 2; /* BLK = 00 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 */
ctr_start (find_cipher ("memcpy()"), count, key, 8, 0, &ctr);
ctr_encrypt (blk, ct, 8, &ctr); /* expect: FF 00 00 00 00 00 00 00 */
ctr_encrypt (blk + 8, ct + 8, 8, &ctr); /* expect: 00 03 00 00 00 00 00 00 */
ctr_encrypt (blk, ct, 8, &ctr); /* expect: FF 00 00 00 00 00 00 00 */
ctr_encrypt (blk + 8, ct + 8, 8, &ctr); /* expect: 00 03 00 00 00 00 00 00 */
if (memcmp (ct, test, 16)) {
printf ("CTR failed logical testing.\n");
for (x = 0; x < 16; x++)
@ -520,7 +520,7 @@ rsa_test (void)
/* encrypt a short 8 byte string */
if ((errnum =
rsa_make_key (&prng, find_prng ("yarrow"), 1024 / 8, 65537,
&key)) != CRYPT_OK) {
&key)) != CRYPT_OK) {
printf ("Error: %s\n", error_to_string (errnum));
exit (-1);
}
@ -555,7 +555,7 @@ rsa_test (void)
y = sizeof (out);
if ((errnum =
rsa_encrypt_key (in, 16, out, &y, &prng, find_prng ("yarrow"),
&key)) != CRYPT_OK) {
&key)) != CRYPT_OK) {
printf ("Error: %s\n", error_to_string (errnum));
exit (-1);
}
@ -614,47 +614,47 @@ rsa_test (void)
for (z = 1024; z <= limit; z += 512) {
t = XCLOCK ();
for (tt = 0; tt < 3; tt++) {
if ((errnum =
rsa_make_key (&prng, find_prng ("yarrow"), z / 8, 65537,
&key)) != CRYPT_OK) {
printf ("Error: %s\n", error_to_string (errnum));
exit (-1);
}
if (tt < 2)
rsa_free (&key);
if ((errnum =
rsa_make_key (&prng, find_prng ("yarrow"), z / 8, 65537,
&key)) != CRYPT_OK) {
printf ("Error: %s\n", error_to_string (errnum));
exit (-1);
}
if (tt < 2)
rsa_free (&key);
}
t = XCLOCK () - t;
printf ("Took %.0f ms to make a %ld-bit RSA key.\n",
1000.0 * (((double) t / 3.0) / (double) XCLOCKS_PER_SEC), z);
1000.0 * (((double) t / 3.0) / (double) XCLOCKS_PER_SEC), z);
/* time encryption */
t = XCLOCK ();
for (tt = 0; tt < 100; tt++) {
y = sizeof (in);
if ((errnum =
rsa_exptmod (in, 8, out, &y, PK_PUBLIC, &key)) != CRYPT_OK) {
printf ("Error: %s\n", error_to_string (errnum));
exit (-1);
}
for (tt = 0; tt < 20; tt++) {
y = sizeof (in);
if ((errnum =
rsa_exptmod (in, 8, out, &y, PK_PUBLIC, &key)) != CRYPT_OK) {
printf ("Error: %s\n", error_to_string (errnum));
exit (-1);
}
}
t = XCLOCK () - t;
printf ("Took %.0f ms to encrypt with a %ld-bit RSA key.\n",
1000.0 * (((double) t / 100.0) / (double) XCLOCKS_PER_SEC), z);
1000.0 * (((double) t / 20.0) / (double) XCLOCKS_PER_SEC), z);
/* time decryption */
t = XCLOCK ();
for (tt = 0; tt < 100; tt++) {
x = sizeof (out);
if ((errnum =
rsa_exptmod (out, y, in, &x, PK_PRIVATE, &key)) != CRYPT_OK) {
printf ("Error: %s\n", error_to_string (errnum));
exit (-1);
}
for (tt = 0; tt < 20; tt++) {
x = sizeof (out);
if ((errnum =
rsa_exptmod (out, y, in, &x, PK_PRIVATE, &key)) != CRYPT_OK) {
printf ("Error: %s\n", error_to_string (errnum));
exit (-1);
}
}
t = XCLOCK () - t;
printf ("Took %.0f ms to decrypt with a %ld-bit RSA key.\n",
1000.0 * (((double) t / 100.0) / (double) XCLOCKS_PER_SEC), z);
1000.0 * (((double) t / 20.0) / (double) XCLOCKS_PER_SEC), z);
rsa_free (&key);
}
}
@ -765,9 +765,9 @@ time_hash (void)
}
t1 = XCLOCK () - t1;
printf ("%-20s: Hash at %5.2f Mbit/sec\n", hash_descriptor[x].name,
((8.0 * 4096.0) *
((double) y / ((double) t1 / (double) XCLOCKS_PER_SEC))) /
1000000.0);
((8.0 * 4096.0) *
((double) y / ((double) t1 / (double) XCLOCKS_PER_SEC))) /
1000000.0);
}
}
@ -783,7 +783,7 @@ time_ecb (void)
printf ("ECB Time Trials for the Symmetric Ciphers:\n");
for (x = 0; cipher_descriptor[x].name != NULL; x++) {
cipher_descriptor[x].setup (key, cipher_descriptor[x].min_key_length, 0,
&skey);
&skey);
#define DO1 func(pt,pt,&skey);
#define DO2 DO1 DO1
@ -816,9 +816,9 @@ time_ecb (void)
("%-20s: Encrypt at %5.2f Mbit/sec and Decrypt at %5.2f Mbit/sec\n",
cipher_descriptor[x].name,
((8.0 * (double) cipher_descriptor[x].block_length) *
((double) y1 / ((double) t1 / (double) XCLOCKS_PER_SEC))) / 1000000.0,
((double) y1 / ((double) t1 / (double) XCLOCKS_PER_SEC))) / 1000000.0,
((8.0 * (double) cipher_descriptor[x].block_length) *
((double) y2 / ((double) t2 / (double) XCLOCKS_PER_SEC))) /
((double) y2 / ((double) t2 / (double) XCLOCKS_PER_SEC))) /
1000000.0);
#undef DO256
@ -843,7 +843,7 @@ dh_tests (void)
dh_key usera, userb;
clock_t t1;
/* if ((errnum = dh_test()) != CRYPT_OK) printf("DH Error: %s\n", error_to_string(errnum)); */
/* if ((errnum = dh_test()) != CRYPT_OK) printf("DH Error: %s\n", error_to_string(errnum)); */
dh_sizes (&low, &high);
printf ("DH Keys from %d to %d supported.\n", low * 8, high * 8);
@ -921,12 +921,12 @@ dh_tests (void)
for (ii = 0; ii < (int) (sizeof (sizes) / sizeof (sizes[0])); ii++) {
t1 = XCLOCK ();
for (tt = 0; tt < 5; tt++) {
dh_make_key (&prng, find_prng ("yarrow"), sizes[ii], &usera);
dh_free (&usera);
dh_make_key (&prng, find_prng ("yarrow"), sizes[ii], &usera);
dh_free (&usera);
}
t1 = XCLOCK () - t1;
printf ("Make dh-%d key took %f msec\n", sizes[ii] * 8,
1000.0 * (((double) t1 / 5.0) / (double) XCLOCKS_PER_SEC));
1000.0 * (((double) t1 / 5.0) / (double) XCLOCKS_PER_SEC));
}
}
@ -937,7 +937,7 @@ dh_tests (void)
y = sizeof (buf[1]);
if ((errnum =
dh_encrypt_key (buf[0], 16, buf[1], &y, &prng, find_prng ("yarrow"),
find_hash ("md5"), &usera)) != CRYPT_OK) {
find_hash ("md5"), &usera)) != CRYPT_OK) {
printf ("Error: %s\n", error_to_string (errnum));
exit (-1);
}
@ -965,7 +965,7 @@ dh_tests (void)
x = sizeof (buf[1]);
if ((errnum =
dh_sign_hash (buf[0], 16, buf[1], &x, &prng, find_prng ("yarrow"),
&usera)) != CRYPT_OK) {
&usera)) != CRYPT_OK) {
printf ("Error: %s\n", error_to_string (errnum));
exit (-1);
}
@ -979,8 +979,8 @@ dh_tests (void)
exit (-1);
}
printf ("dh_sign/verify_hash: %s (%d,%d), %lu\n",
((stat == 1)
&& (stat2 == 0)) ? "passed" : "failed", stat, stat2, x);
((stat == 1)
&& (stat2 == 0)) ? "passed" : "failed", stat, stat2, x);
dh_free (&usera);
}
#else
@ -1013,7 +1013,7 @@ rng_tests (void)
x = rng_get_bytes (buf, sizeof (buf), &callback);
t1 = XCLOCK () - t1;
printf (" %f bytes per second...",
(double) x / ((double) t1 / (double) XCLOCKS_PER_SEC));
(double) x / ((double) t1 / (double) XCLOCKS_PER_SEC));
printf ("read %d bytes.\n ", x);
for (y = 0; y < x; y++)
printf ("%02x ", buf[y]);
@ -1022,7 +1022,7 @@ rng_tests (void)
#ifdef YARROW
if ((errnum =
rng_make_prng (128, find_prng ("yarrow"), &prng,
&callback)) != CRYPT_OK) {
&callback)) != CRYPT_OK) {
printf (" starting yarrow error: %s\n", error_to_string (errnum));
exit (-1);
}
@ -1123,18 +1123,18 @@ ecc_tests (void)
for (ii = 0; ii < (int) (sizeof (sizes) / sizeof (sizes[0])); ii++) {
t1 = XCLOCK ();
for (tt = 0; tt < 25; tt++) {
if ((errnum =
ecc_make_key (&prng, find_prng ("yarrow"), sizes[ii],
&usera)) != CRYPT_OK) {
printf ("Error: %s\n", error_to_string (errnum));
exit (-1);
}
ecc_free (&usera);
for (tt = 0; tt < 10; tt++) {
if ((errnum =
ecc_make_key (&prng, find_prng ("yarrow"), sizes[ii],
&usera)) != CRYPT_OK) {
printf ("Error: %s\n", error_to_string (errnum));
exit (-1);
}
ecc_free (&usera);
}
t1 = XCLOCK () - t1;
printf ("Make ECC-%d key took %f msec\n", sizes[ii] * 8,
1000.0 * (((double) t1 / 25.0) / (double) XCLOCKS_PER_SEC));
1000.0 * (((double) t1 / 10.0) / (double) XCLOCKS_PER_SEC));
}
}
@ -1145,7 +1145,7 @@ ecc_tests (void)
y = sizeof (buf[1]);
if ((errnum =
ecc_encrypt_key (buf[0], 32, buf[1], &y, &prng, find_prng ("yarrow"),
find_hash ("sha256"), &usera)) != CRYPT_OK) {
find_hash ("sha256"), &usera)) != CRYPT_OK) {
printf ("Error: %s\n", error_to_string (errnum));
exit (-1);
}
@ -1172,7 +1172,7 @@ ecc_tests (void)
x = sizeof (buf[1]);
if ((errnum =
ecc_sign_hash (buf[0], 16, buf[1], &x, &prng, find_prng ("yarrow"),
&usera)) != CRYPT_OK) {
&usera)) != CRYPT_OK) {
printf ("Error: %s\n", error_to_string (errnum));
exit (-1);
}
@ -1187,7 +1187,7 @@ ecc_tests (void)
exit (-1);
}
printf ("ecc_sign/verify_hash: %s (%d,%d)\n",
((stat == 1) && (stat2 == 0)) ? "passed" : "failed", stat, stat2);
((stat == 1) && (stat2 == 0)) ? "passed" : "failed", stat, stat2);
ecc_free (&usera);
}
#else
@ -1342,15 +1342,15 @@ register_all_algs (void)
register_cipher (&null_desc);
#ifdef SHA1
register_hash (&sha1_desc);
#endif
#ifdef SHA256
register_hash (&sha256_desc);
#endif
#ifdef TIGER
register_hash (&tiger_desc);
#endif
#ifdef SHA1
register_hash (&sha1_desc);
#endif
#ifdef MD5
register_hash (&md5_desc);
#endif
@ -1383,8 +1383,8 @@ kr_display (pk_key * kr)
while (kr->system != NON_KEY) {
printf ("CRC [%08lx], System [%10s], Type [%20s], %s, %s, %s\n", kr->ID,
sys[kr->system], type[kr->key_type], kr->name, kr->email,
kr->description);
sys[kr->system], type[kr->key_type], kr->name, kr->email,
kr->description);
kr = kr->next;
}
printf ("\n");
@ -1402,7 +1402,7 @@ kr_test_makekeys (pk_key ** kr)
printf ("KR: Making DH key...\n");
if ((errnum =
kr_make_key (*kr, &prng, find_prng ("yarrow"), DH_KEY, 128, "dhkey",
"dh@dh.dh", "dhkey one")) != CRYPT_OK) {
"dh@dh.dh", "dhkey one")) != CRYPT_OK) {
printf ("Make key error: %s\n", error_to_string (errnum));
exit (-1);
}
@ -1411,7 +1411,7 @@ kr_test_makekeys (pk_key ** kr)
printf ("KR: Making ECC key...\n");
if ((errnum =
kr_make_key (*kr, &prng, find_prng ("yarrow"), ECC_KEY, 20, "ecckey",
"ecc@ecc.ecc", "ecckey one")) != CRYPT_OK) {
"ecc@ecc.ecc", "ecckey one")) != CRYPT_OK) {
printf ("Make key error: %s\n", error_to_string (errnum));
exit (-1);
}
@ -1420,7 +1420,7 @@ kr_test_makekeys (pk_key ** kr)
printf ("KR: Making RSA key...\n");
if ((errnum =
kr_make_key (*kr, &prng, find_prng ("yarrow"), RSA_KEY, 128, "rsakey",
"rsa@rsa.rsa", "rsakey one")) != CRYPT_OK) {
"rsa@rsa.rsa", "rsakey one")) != CRYPT_OK) {
printf ("Make key error: %s\n", error_to_string (errnum));
exit (-1);
}
@ -1533,12 +1533,12 @@ kr_test (void)
_kr = kr;
for (i = 0; i < 3; i++) {
printf ("Testing a key with system %d, type %d:\t", _kr->system,
_kr->key_type);
_kr->key_type);
len = sizeof (buf2);
if ((errnum =
kr_encrypt_key (kr, _kr->ID, buf, 16, buf2, &len, &prng,
find_prng ("yarrow"),
find_hash ("md5"))) != CRYPT_OK) {
kr_encrypt_key (kr, _kr->ID, buf, 16, buf2, &len, &prng,
find_prng ("yarrow"),
find_hash ("md5"))) != CRYPT_OK) {
printf ("Encrypt error, %d, %s\n", i, error_to_string (errnum));
exit (-1);
}
@ -1555,8 +1555,8 @@ kr_test (void)
len = sizeof (buf2);
if ((errnum =
kr_sign_hash (kr, _kr->ID, buf, 32, buf2, &len, &prng,
find_prng ("yarrow"))) != CRYPT_OK) {
kr_sign_hash (kr, _kr->ID, buf, 32, buf2, &len, &prng,
find_prng ("yarrow"))) != CRYPT_OK) {
printf ("kr_sign_hash failed, %i, %s\n", i, error_to_string (errnum));
exit (-1);
}
@ -1576,8 +1576,8 @@ kr_test (void)
len = sizeof (buf);
if ((errnum =
kr_fingerprint (kr, _kr->ID, find_hash ("sha1"), buf,
&len)) != CRYPT_OK) {
kr_fingerprint (kr, _kr->ID, find_hash ("sha1"), buf,
&len)) != CRYPT_OK) {
printf ("kr_fingerprint failed, %i, %lu\n", i, len);
exit (-1);
}
@ -1585,7 +1585,7 @@ kr_test (void)
for (j = 0; j < 20; j++) {
printf ("%02x", buf[j]);
if (j < 19)
printf (":");
printf (":");
}
printf ("\n\n");
@ -1633,8 +1633,8 @@ kr_test (void)
len = sizeof (buf3);
if ((errnum =
kr_encrypt_key (kr, kr->ID, buf, 16, buf3, &len, &prng,
find_prng ("yarrow"),
find_hash ("md5"))) != CRYPT_OK) {
find_prng ("yarrow"),
find_hash ("md5"))) != CRYPT_OK) {
printf ("Encrypt error, %d, %s\n", i, error_to_string (errnum));
exit (-1);
}

8
des.c
View File

@ -519,6 +519,9 @@ void des3_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key
int des_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
int err;
static const struct des_test_case {
int num, mode; // mode 1 = encrypt
@ -648,10 +651,14 @@ int des_test(void)
}
return CRYPT_OK;
#endif
}
int des3_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
unsigned char key[24], pt[8], ct[8], tmp[8];
symmetric_key skey;
int x, err;
@ -680,6 +687,7 @@ int des3_test(void)
}
return CRYPT_OK;
#endif
}
int des_keysize(int *desired_keysize)

48
dh.c
View File

@ -109,7 +109,7 @@ static const struct {
#ifdef DH4096
{
512,
"DH-4096",
"DH-4096",
"3",
"Id8ukxZdao3hS0NGTKAXdt3c8PpiyigIyBY8lwOHjM2cqkaZgwvr1pA6OowS"
"32kJkeOqKB8gNTZZZVqOFkPXgvC4WveUgA5a7rhTj28pDidNROmMO70CCcSw"
@ -125,7 +125,7 @@ static const struct {
"PT0+ZAUyLSAVHbsul++cawh"
},
#endif
{
{
0,
NULL,
NULL,
@ -160,7 +160,7 @@ int dh_test(void)
/* ensure p is prime */
if ((res = is_prime(&p, &primality)) != CRYPT_OK) { goto done; }
if (primality == 0) {
if (primality == 0) {
res = CRYPT_FAIL_TESTVECTOR;
goto done;
}
@ -213,7 +213,7 @@ int dh_get_size(dh_key *key)
return INT_MAX; /* large value that would cause dh_make_key() to fail */
}
}
int dh_make_key(prng_state *prng, int wprng, int keysize, dh_key *key)
{
unsigned char buf[512];
@ -232,7 +232,7 @@ int dh_make_key(prng_state *prng, int wprng, int keysize, dh_key *key)
for (x = 0; (keysize > sets[x].size) && (sets[x].size != 0); x++);
#ifdef FAST_PK
keysize = MIN(sets[x].size, 32);
#else
#else
keysize = sets[x].size;
#endif
@ -257,7 +257,7 @@ int dh_make_key(prng_state *prng, int wprng, int keysize, dh_key *key)
if (mp_read_unsigned_bin(&key->x, buf, keysize) != MP_OKAY) { goto error; }
if (mp_exptmod(&g, &key->x, &p, &key->y) != MP_OKAY) { goto error; }
key->type = PK_PRIVATE;
if (mp_shrink(&key->x) != MP_OKAY) { goto error; }
if (mp_shrink(&key->y) != MP_OKAY) { goto error; }
@ -341,11 +341,11 @@ int dh_export(unsigned char *out, unsigned long *outlen, int type, dh_key *key)
/* export y */
OUTPUT_BIGNUM(&key->y, buf2, y, z);
if (type == PK_PRIVATE) {
if (type == PK_PRIVATE) {
/* export x */
OUTPUT_BIGNUM(&key->x, buf2, y, z);
}
/* check for overflow */
if (*outlen < y) {
#ifdef CLEAN_STACK
@ -362,9 +362,9 @@ int dh_export(unsigned char *out, unsigned long *outlen, int type, dh_key *key)
memcpy(out, buf2, (size_t)y);
/* clear mem */
#ifdef CLEAN_STACK
#ifdef CLEAN_STACK
zeromem(buf2, sizeof(buf2));
#endif
#endif
return CRYPT_OK;
}
@ -376,24 +376,30 @@ int dh_import(const unsigned char *in, unsigned long inlen, dh_key *key)
_ARGCHK(in != NULL);
_ARGCHK(key != NULL);
/* check type byte */
if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_DH, PACKET_SUB_KEY)) != CRYPT_OK) {
return err;
}
/* make sure valid length */
if (2+PACKET_SIZE > inlen) {
return CRYPT_INVALID_PACKET;
}
/* check type byte */
if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_DH, PACKET_SUB_KEY)) != CRYPT_OK) {
return err;
}
/* init */
if (mp_init_multi(&key->x, &key->y, NULL) != MP_OKAY) {
if (mp_init_multi(&key->x, &key->y, NULL) != MP_OKAY) {
return CRYPT_MEM;
}
/* advance past packet header */
y = PACKET_SIZE;
/* key type, e.g. private, public */
key->type = (int)in[y++];
/* key size in bytes */
s = (unsigned long)in[y++] * 8;
for (x = 0; (s > (unsigned long)sets[x].size) && (sets[x].size != 0); x++);
if (sets[x].size == 0) {
err = CRYPT_INVALID_KEYSIZE;
@ -423,7 +429,7 @@ int dh_import(const unsigned char *in, unsigned long inlen, dh_key *key)
/* eliminate private key if public */
if (key->type == PK_PUBLIC) {
mp_clear(&key->x);
}
}
return CRYPT_OK;
error:
@ -431,7 +437,7 @@ error:
return err;
}
int dh_shared_secret(dh_key *private_key, dh_key *public_key,
int dh_shared_secret(dh_key *private_key, dh_key *public_key,
unsigned char *out, unsigned long *outlen)
{
mp_int tmp, p;
@ -454,7 +460,7 @@ int dh_shared_secret(dh_key *private_key, dh_key *public_key,
}
/* compute y^x mod p */
if (mp_init_multi(&tmp, &p, NULL) != MP_OKAY) {
if (mp_init_multi(&tmp, &p, NULL) != MP_OKAY) {
return CRYPT_MEM;
}
@ -467,7 +473,7 @@ int dh_shared_secret(dh_key *private_key, dh_key *public_key,
res = CRYPT_BUFFER_OVERFLOW;
goto done;
}
(void)mp_to_unsigned_bin(&tmp, out);
if (mp_to_unsigned_bin(&tmp, out) != MP_OKAY) { goto error; }
*outlen = x;
res = CRYPT_OK;
goto done;

View File

@ -194,7 +194,24 @@ done:
return res;
}
/* perform an ElGamal Signature of a hash
*
* The math works as follows. x is the private key, M is the message to sign
1. pick a random k
2. compute a = g^k mod p
3. compute b = (M - xa)/k mod p
4. Send (a,b)
Now to verify with y=g^x mod p, a and b
1. compute y^a * a^b = g^(xa) * g^(k*(M-xa)/k)
= g^(xa + (M - xa))
= g^M [all mod p]
2. Compare against g^M mod p [based on input hash].
3. If result of #2 == result of #1 then signature valid
*/
int dh_sign_hash(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen,
prng_state *prng, int wprng, dh_key *key)

166
ecc.c
View File

@ -30,7 +30,7 @@ static const struct {
},
#endif
#ifdef ECC192
{
{
24,
"ECC-192",
/* prime */
@ -65,7 +65,7 @@ static const struct {
/* Gx */
"jpqOf1BHus6Yd/pyhyVpP",
/* Gy */
"3FCtyo2yHA5SFjkCGbYxbOvNeChwS+j6wSIwck",
},
@ -88,7 +88,7 @@ static const struct {
/* Gy */
"4/ZGkB+6d+RZkVhIdmFdXOhpZDNQp5UpiksG6Wtlr7r"
},
},
#endif
#ifdef ECC384
{
@ -97,11 +97,11 @@ static const struct {
/* prime */
"//////////////////////////////////////////x/////00000000003/"
"////",
/* B */
"ip4lf+8+v+IOZWLhu/Wj6HWTd6x+WK4I0nG8Zr0JXrh6LZcDYYxHdIg5oEtJ"
"x2hl",
/* Order */
"////////////////////////////////nsDDWVGtBTzO6WsoIB2dUkpi6MhC"
"nIbp",
@ -109,7 +109,7 @@ static const struct {
/* Gx and Gy */
"geVA8hwB1JUEiSSUyo2jT6uTEsABfvkOMVT1u89KAZXL0l9TlrKfR3fKNZXo"
"TWgt",
"DXVUIfOcB6zTdfY/afBSAVZq7RqecXHywTen4xNmkC0AOB7E7Nw1dNf37NoG"
"wWvV"
},
@ -118,22 +118,22 @@ static const struct {
{
65,
"ECC-521",
/* prime */
/* prime */
"V///////////////////////////////////////////////////////////"
"///////////////////////////",
/* B */
"56LFhbXZXoQ7vAQ8Q2sXK3kejfoMvcp5VEuj8cHZl49uLOPEL7iVfDx5bB0l"
"JknlmSrSz+8FImqyUz57zHhK3y0",
/* Order */
/* Order */
"V//////////////////////////////////////////+b66XuE/BvPhVym1I"
"FS9fT0xjScuYPn7hhjljnwHE6G9",
/* Gx and Gy */
"CQ5ZWQt10JfpPu+osOZbRH2d6I1EGK/jI7uAAzWQqqzkg5BNdVlvrae/Xt19"
"wB/gDupIBF1XMf2c/b+VZ72vRrc",
"HWvAMfucZl015oANxGiVHlPcFL4ILURH6WNhxqN9pvcB9VkSfbUz2P0nL2v0"
"J+j1s4rF726edB2G8Y+b7QVqMPG",
},
@ -189,7 +189,7 @@ void ecc_find_base(void)
mp_sqrmod(&tmp2, &p, &tmp2);
/* tmp2 should equal tmp1 */
} while (mp_cmp(&tmp1, &tmp2));
} while (mp_cmp(&tmp1, &tmp2));
/* now output values in way that libtomcrypt wants */
mp_todecimal(&p, buf);
@ -249,8 +249,8 @@ static int dbl_point(ecc_point *P, ecc_point *R, mp_int *modulus, mp_int *mu)
{
mp_int s, tmp, tmpx;
int res;
if (mp_init_multi(&s, &tmp, &tmpx, NULL) != MP_OKAY) {
if (mp_init_multi(&s, &tmp, &tmpx, NULL) != MP_OKAY) {
return CRYPT_MEM;
}
@ -293,8 +293,8 @@ static int add_point(ecc_point *P, ecc_point *Q, ecc_point *R, mp_int *modulus,
{
mp_int s, tmp, tmpx;
int res;
if (mp_init(&tmp) != MP_OKAY) {
if (mp_init(&tmp) != MP_OKAY) {
return CRYPT_MEM;
}
@ -303,14 +303,14 @@ static int add_point(ecc_point *P, ecc_point *Q, ecc_point *R, mp_int *modulus,
mp_clear(&tmp);
return CRYPT_MEM;
}
if (mp_cmp(&P->x, &Q->x) == MP_EQ)
if (mp_cmp(&P->y, &Q->y) == MP_EQ || mp_cmp(&P->y, &tmp) == MP_EQ) {
mp_clear(&tmp);
return dbl_point(P, R, modulus, mu);
}
if (mp_init_multi(&tmpx, &s, NULL) != MP_OKAY) {
if (mp_init_multi(&tmpx, &s, NULL) != MP_OKAY) {
mp_clear(&tmp);
return CRYPT_MEM;
}
@ -360,7 +360,7 @@ static int ecc_mulmod(mp_int *k, ecc_point *G, ecc_point *R, mp_int *modulus)
mp_int mu;
mp_digit buf;
int first, bitbuf, bitcpy, bitcnt, mode, digidx;
/* init barrett reduction */
if (mp_init(&mu) != MP_OKAY) {
return CRYPT_MEM;
@ -369,7 +369,7 @@ static int ecc_mulmod(mp_int *k, ecc_point *G, ecc_point *R, mp_int *modulus)
mp_clear(&mu);
return CRYPT_MEM;
}
/* alloc ram for window temps */
for (i = 0; i < 8; i++) {
M[i] = new_point();
@ -381,7 +381,7 @@ static int ecc_mulmod(mp_int *k, ecc_point *G, ecc_point *R, mp_int *modulus)
return CRYPT_MEM;
}
}
/* make a copy of G incase R==G */
tG = new_point();
if (tG == NULL) { goto error; }
@ -391,12 +391,12 @@ static int ecc_mulmod(mp_int *k, ecc_point *G, ecc_point *R, mp_int *modulus)
if (dbl_point(G, M[0], 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; }
@ -408,13 +408,13 @@ static int ecc_mulmod(mp_int *k, ecc_point *G, ecc_point *R, mp_int *modulus)
digidx = k->used - 1;
bitcpy = bitbuf = 0;
first = 1;
/* perform ops */
for (;;) {
/* grab next digit as required */
if (--bitcnt == 0) {
if (digidx == -1) {
break;
break;
}
buf = k->dp[digidx--];
bitcnt = (int) DIGIT_BIT;
@ -423,17 +423,18 @@ static int ecc_mulmod(mp_int *k, ecc_point *G, ecc_point *R, mp_int *modulus)
/* 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; }
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;
@ -442,39 +443,35 @@ static int ecc_mulmod(mp_int *k, ecc_point *G, ecc_point *R, mp_int *modulus)
/* 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; }
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 {
/* 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; }
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; }
}
/* then add, bitbuf will be 8..15 [8..2^WINSIZE] guaranteed */
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; }
if (dbl_point(R, R, modulus, &mu) != CRYPT_OK) { goto error; }
}
bitbuf <<= 1;
if ((bitbuf & (1 << WINSIZE)) != 0) {
if (first == 1){
@ -489,7 +486,7 @@ static int ecc_mulmod(mp_int *k, ecc_point *G, ecc_point *R, mp_int *modulus)
}
}
}
res = CRYPT_OK;
res = CRYPT_OK;
goto done;
error:
res = CRYPT_MEM;
@ -510,18 +507,18 @@ int ecc_test(void)
ecc_point *G, *GG;
int i, res, primality;
if (mp_init_multi(&modulus, &order, NULL) != MP_OKAY) {
if (mp_init_multi(&modulus, &order, NULL) != MP_OKAY) {
return CRYPT_MEM;
}
G = new_point();
if (G == NULL) {
if (G == NULL) {
mp_clear_multi(&modulus, &order, NULL);
return CRYPT_MEM;
}
GG = new_point();
if (GG == NULL) {
if (GG == NULL) {
mp_clear_multi(&modulus, &order, NULL);
del_point(G);
return CRYPT_MEM;
@ -540,7 +537,7 @@ int ecc_test(void)
res = CRYPT_FAIL_TESTVECTOR;
goto done1;
}
/* is order prime ? */
if (is_prime(&order, &primality) != CRYPT_OK) { goto error; }
if (primality == 0) {
@ -579,11 +576,11 @@ void ecc_sizes(int *low, int *high)
*low = INT_MAX;
*high = 0;
for (i = 0; sets[i].size != 0; i++) {
if (sets[i].size < *low) {
*low = sets[i].size;
if (sets[i].size < *low) {
*low = sets[i].size;
}
if (sets[i].size > *high) {
*high = sets[i].size;
if (sets[i].size > *high) {
*high = sets[i].size;
}
}
}
@ -606,7 +603,7 @@ int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key)
for (x = 0; (keysize > sets[x].size) && (sets[x].size != 0); x++);
keysize = sets[x].size;
if (sets[x].size == 0) {
if (sets[x].size == 0) {
return CRYPT_INVALID_KEYSIZE;
}
key->idx = x;
@ -617,7 +614,7 @@ int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key)
}
/* setup the key variables */
if (mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->k, &prime, NULL) != MP_OKAY) {
if (mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->k, &prime, NULL) != MP_OKAY) {
return CRYPT_MEM;
}
base = new_point();
@ -635,7 +632,7 @@ int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key)
/* make the public key */
if (ecc_mulmod(&key->k, base, &key->pubkey, &prime) != CRYPT_OK) { goto error; }
key->type = PK_PRIVATE;
/* shrink key */
if (mp_shrink(&key->k) != MP_OKAY) { goto error; }
if (mp_shrink(&key->pubkey.x) != MP_OKAY) { goto error; }
@ -689,12 +686,12 @@ static int compress_y_point(ecc_point *pt, int idx, int *result)
if (mp_exptmod(&tmp, &tmp2, &p, &tmp) != MP_OKAY) { goto error; } /* tmp = (x^3 - 3x + b)^((p+1)/4) mod p */
/* if tmp equals the y point give a 0, otherwise 1 */
if (mp_cmp(&tmp, &pt->y) == 0) {
if (mp_cmp(&tmp, &pt->y) == 0) {
*result = 0;
} else {
*result = 1;
}
res = CRYPT_OK;
goto done;
error:
@ -710,7 +707,7 @@ static int expand_y_point(ecc_point *pt, int idx, int result)
int res;
_ARGCHK(pt != NULL);
if (mp_init_multi(&tmp, &tmp2, &p, NULL) != MP_OKAY) {
return CRYPT_MEM;
}
@ -736,7 +733,7 @@ static int expand_y_point(ecc_point *pt, int idx, int result)
} else {
if (mp_sub(&p, &tmp, &pt->y) != MP_OKAY) { goto error; }
}
res = CRYPT_OK;
goto done;
error:
@ -795,8 +792,8 @@ int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key
_ARGCHK(key != NULL);
/* type valid? */
if (key->type != PK_PRIVATE && type == PK_PRIVATE) {
return CRYPT_PK_TYPE_MISMATCH;
if (key->type != PK_PRIVATE && type == PK_PRIVATE) {
return CRYPT_PK_TYPE_MISMATCH;
}
/* output type and magic byte */
@ -818,7 +815,7 @@ int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key
}
/* check size */
if (*outlen < y) {
if (*outlen < y) {
return CRYPT_BUFFER_OVERFLOW;
}
@ -842,15 +839,16 @@ int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key)
_ARGCHK(in != NULL);
_ARGCHK(key != NULL);
/* check type */
if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_ECC, PACKET_SUB_KEY)) != CRYPT_OK) {
return err;
}
/* check length */
if (2+PACKET_SIZE > inlen) {
return CRYPT_INVALID_PACKET;
}
/* check type */
if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_ECC, PACKET_SUB_KEY)) != CRYPT_OK) {
return err;
}
/* init key */
if (mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->k, NULL) != MP_OKAY) {
return CRYPT_MEM;
@ -859,9 +857,9 @@ int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key)
y = PACKET_SIZE;
key->type = (int)in[y++];
s = (unsigned long)in[y++];
for (x = 0; (s > (unsigned long)sets[x].size) && (sets[x].size != 0); x++);
if (sets[x].size == 0) {
if (sets[x].size == 0) {
err = CRYPT_INVALID_KEYSIZE;
goto error;
}
@ -881,30 +879,30 @@ int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key)
/* load x coordinate */
INPUT_BIGNUM(&key->pubkey.x, in, x, y);
/* load y */
x = (unsigned long)in[y++];
if ((err = expand_y_point(&key->pubkey, key->idx, (int)x)) != CRYPT_OK) {
goto error;
if ((err = expand_y_point(&key->pubkey, key->idx, (int)x)) != CRYPT_OK) {
goto error;
}
if (key->type == PK_PRIVATE) {
/* load private key */
INPUT_BIGNUM(&key->k, in, x, y);
}
/* eliminate private key if public */
if (key->type == PK_PUBLIC) {
mp_clear(&key->k);
}
}
return CRYPT_OK;
error:
mp_clear_multi(&key->pubkey.x, &key->pubkey.y, &key->k, NULL);
return err;
}
int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key,
int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key,
unsigned char *out, unsigned long *outlen)
{
unsigned long x, y;
@ -928,17 +926,17 @@ int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key,
/* make new point */
result = new_point();
if (result == NULL) {
if (result == NULL) {
return CRYPT_MEM;
}
if (mp_init(&prime) != MP_OKAY) {
if (mp_init(&prime) != MP_OKAY) {
del_point(result);
return CRYPT_MEM;
}
if (mp_read_radix(&prime, (unsigned char *)sets[private_key->idx].prime, 64) != MP_OKAY) { goto error; }
if ((err = ecc_mulmod(&private_key->k, &public_key->pubkey, result, &prime)) != CRYPT_OK) { res = err; goto done1; }
if (mp_read_radix(&prime, (unsigned char *)sets[private_key->idx].prime, 64) != MP_OKAY) { goto error; }
if ((res = ecc_mulmod(&private_key->k, &public_key->pubkey, result, &prime)) != CRYPT_OK) { goto done1; }
x = (unsigned long)mp_unsigned_bin_size(&result->x);
y = (unsigned long)mp_unsigned_bin_size(&result->y);
@ -948,8 +946,8 @@ int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key,
goto done1;
}
*outlen = x+y;
(void)mp_to_unsigned_bin(&result->x, out);
(void)mp_to_unsigned_bin(&result->y, out+x);
if (mp_to_unsigned_bin(&result->x, out) != MP_OKAY) { goto error; }
if (mp_to_unsigned_bin(&result->y, out+x) != MP_OKAY) { goto error; }
res = CRYPT_OK;
goto done1;

View File

@ -299,7 +299,19 @@ done1:
return res;
}
/* verify that mG = (bA + Y) */
/* verify that mG = (bA + Y)
*
* The signatures work by making up a fresh key "a" with a public key "A". Now we want to sign so the
* public key Y = xG can verify it.
*
* b = (m - x)/k, A is the public key embedded and Y is the users public key [who signed it]
* A = kG therefore bA == ((m-x)/k)kG == (m-x)G
*
* Adding Y = xG to the bA gives us (m-x)G + xG == mG
*
* The user given only xG, kG and b cannot determine k or x which means they can't find the private key.
*
*/
int ecc_verify_hash(const unsigned char *sig, unsigned long siglen,
const unsigned char *hash, unsigned long inlen,
int *stat, ecc_key *key)

6
hmac.c
View File

@ -37,7 +37,7 @@ int hmac_init(hmac_state *hmac, int hash, const unsigned char *key, unsigned lon
return err;
}
if(key == NULL || keylen == 0) {
if (keylen == 0) {
return CRYPT_INVALID_KEYSIZE;
}
@ -231,6 +231,9 @@ Category: Informational R. Glenn
int hmac_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
unsigned char digest[MAXBLOCKSIZE];
int i;
@ -497,6 +500,7 @@ Key First"
} else {
return CRYPT_OK;
}
#endif
}
#endif

View File

@ -9,7 +9,7 @@
# a build. This is easy to remedy though, for those that have problems.
# The version
VERSION=0.83
VERSION=0.84
#ch1-01-1
# Compiler and Linker Names
@ -31,7 +31,7 @@ CFLAGS += -c -I./ -Wall -Wsign-compare -W -Wno-unused -Wshadow -Werror
# optimize for SIZE
CFLAGS += -Os
# compile for DEBUGGING
# compile for DEBUGING
#CFLAGS += -g3
#ch1-01-3
@ -57,7 +57,7 @@ OBJECTS=keyring.o gf.o mem.o sprng.o ecc.o base64.o dh.o rsa.o \
bits.o yarrow.o cfb.o ofb.o ecb.o ctr.o cbc.o hash.o tiger.o sha1.o \
md5.o md4.o md2.o sha256.o sha512.o xtea.o aes.o serpent.o des.o \
safer_tab.o safer.o safer+.o rc4.o rc2.o rc6.o rc5.o cast5.o noekeon.o blowfish.o crypt.o \
ampi.o mpi.o prime.o twofish.o packet.o hmac.o strings.o
mpi.o prime.o twofish.o packet.o hmac.o strings.o
TESTOBJECTS=demos/test.o
HASHOBJECTS=demos/hashsum.o
@ -71,7 +71,7 @@ LEFTOVERS=*.dvi *.log *.aux *.toc *.idx *.ilg *.ind
COMPRESSED=crypt.tar.bz2 crypt.zip crypt.tar.gz
#Header files used by libtomcrypt.
HEADERS=mpi.h mycrypt_cfg.h mycrypt_gf.h mycrypt_kr.h \
HEADERS=tommath.h mycrypt_cfg.h mycrypt_gf.h mycrypt_kr.h \
mycrypt_misc.h mycrypt_prng.h mycrypt_cipher.h mycrypt_hash.h \
mycrypt_macros.h mycrypt_pk.h mycrypt.h mycrypt_argchk.h mycrypt_custom.h
@ -129,8 +129,7 @@ clean:
#nice pre-compiled crypt.pdf that comes with libtomcrypt! We only need to
#delete it if we are rebuilding it.
docs: crypt.tex
rm -f crypt.pdf
rm -f $(LEFTOVERS)
rm -f crypt.pdf $(LEFTOVERS)
latex crypt > /dev/null
makeindex crypt > /dev/null
pdflatex crypt > /dev/null

View File

@ -2,7 +2,7 @@
#
#Tom St Denis
CFLAGS = /I. /Ogiyb2t /Gs /DWIN32 /W3
CFLAGS = /I. /Ogiyb1s /Gs /DWIN32 /W3
default: library
@ -11,7 +11,7 @@ OBJECTS=keyring.obj gf.obj mem.obj sprng.obj ecc.obj base64.obj dh.obj rsa.obj \
bits.obj yarrow.obj cfb.obj ofb.obj ecb.obj ctr.obj cbc.obj hash.obj tiger.obj sha1.obj \
md5.obj md4.obj md2.obj sha256.obj sha512.obj xtea.obj aes.obj serpent.obj des.obj \
safer_tab.obj safer.obj safer+.obj rc4.obj rc2.obj rc6.obj rc5.obj cast5.obj noekeon.obj \
blowfish.obj crypt.obj ampi.obj mpi.obj prime.obj twofish.obj packet.obj hmac.obj strings.obj
blowfish.obj crypt.obj mpi.obj prime.obj twofish.obj packet.obj hmac.obj strings.obj
library: $(OBJECTS)
lib /out:tomcrypt.lib $(OBJECTS)

4
md2.c
View File

@ -136,6 +136,9 @@ void md2_done(hash_state * md, unsigned char *hash)
int md2_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
char *msg;
unsigned char md[16];
@ -184,6 +187,7 @@ int md2_test(void)
}
}
return CRYPT_OK;
#endif
}
#endif

4
md4.c
View File

@ -221,6 +221,9 @@ void md4_done(hash_state * md, unsigned char *hash)
int md4_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct md4_test_case {
char *input;
unsigned char digest[16];
@ -261,6 +264,7 @@ int md4_test(void)
}
return CRYPT_OK;
#endif
}
#endif

4
md5.c
View File

@ -208,6 +208,9 @@ void md5_done(hash_state * md, unsigned char *hash)
int md5_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
char *msg;
unsigned char hash[16];
@ -249,6 +252,7 @@ int md5_test(void)
}
}
return CRYPT_OK;
#endif
}
#endif

13200
mpi.c

File diff suppressed because it is too large Load Diff

View File

@ -16,8 +16,8 @@ extern "C" {
#endif
/* version */
#define CRYPT 0x0083
#define SCRYPT "0.83"
#define CRYPT 0x0084
#define SCRYPT "0.84"
/* max size of either a cipher/hash block or symmetric key [largest of the two] */
#define MAXBLOCKSIZE 128

View File

@ -1,14 +1,16 @@
/* This header is meant to be included before mycrypt.h in projects where
* you don't want to throw all the defines in a makefile.
* you don't want to throw all the defines in a makefile.
*/
#ifndef MYCRYPT_CUSTOM_H_
#define MYCRYPT_CUSTOM_H_
#ifdef CRYPT
#error mycrypt_custom.h should be included before mycrypt.h
#error mycrypt_custom.h should be included before mycrypt.h
#endif
#define LTC_TEST
#define XMALLOC malloc
#define XREALLOC realloc
#define XCALLOC calloc

View File

@ -169,6 +169,9 @@ void noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_k
int noekeon_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const unsigned char
key[] =
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
@ -193,13 +196,14 @@ int noekeon_test(void)
}
return CRYPT_OK;
#endif
}
int noekeon_keysize(int *desired_keysize)
{
_ARGCHK(desired_keysize != NULL);
if (*desired_keysize < 16) {
return CRYPT_INVALID_KEYSIZE;
return CRYPT_INVALID_KEYSIZE;
} else {
*desired_keysize = 16;
return CRYPT_OK;

147
prime.c
View File

@ -2,144 +2,17 @@
#ifdef MPI
#define UPPER_LIMIT (sizeof(prime_tab) / sizeof(prime_tab[0]))
static const mp_digit prime_tab[] = {
0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013,
0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035,
0x003B, 0x003D, 0x0043, 0x0047, 0x0049, 0x004F, 0x0053, 0x0059,
0x0061, 0x0065, 0x0067, 0x006B, 0x006D, 0x0071, 0x007F, 0x0083,
0x0089, 0x008B, 0x0095, 0x0097, 0x009D, 0x00A3, 0x00A7, 0x00AD,
0x00B3, 0x00B5, 0x00BF, 0x00C1, 0x00C5, 0x00C7, 0x00D3, 0x00DF,
0x00E3, 0x00E5, 0x00E9, 0x00EF, 0x00F1, 0x00FB, 0x0101, 0x0107,
0x010D, 0x010F, 0x0115, 0x0119, 0x011B, 0x0125, 0x0133, 0x0137,
0x0139, 0x013D, 0x014B, 0x0151, 0x015B, 0x015D, 0x0161, 0x0167,
0x016F, 0x0175, 0x017B, 0x017F, 0x0185, 0x018D, 0x0191, 0x0199,
0x01A3, 0x01A5, 0x01AF, 0x01B1, 0x01B7, 0x01BB, 0x01C1, 0x01C9,
0x01CD, 0x01CF, 0x01D3, 0x01DF, 0x01E7, 0x01EB, 0x01F3, 0x01F7,
0x01FD, 0x0209, 0x020B, 0x021D, 0x0223, 0x022D, 0x0233, 0x0239,
0x023B, 0x0241, 0x024B, 0x0251, 0x0257, 0x0259, 0x025F, 0x0265,
0x0269, 0x026B, 0x0277, 0x0281, 0x0283, 0x0287, 0x028D, 0x0293,
0x0295, 0x02A1, 0x02A5, 0x02AB, 0x02B3, 0x02BD, 0x02C5, 0x02CF,
0x02D7, 0x02DD, 0x02E3, 0x02E7, 0x02EF, 0x02F5, 0x02F9, 0x0301,
0x0305, 0x0313, 0x031D, 0x0329, 0x032B, 0x0335, 0x0337, 0x033B,
0x033D, 0x0347, 0x0355, 0x0359, 0x035B, 0x035F, 0x036D, 0x0371,
0x0373, 0x0377, 0x038B, 0x038F, 0x0397, 0x03A1, 0x03A9, 0x03AD,
0x03B3, 0x03B9, 0x03C7, 0x03CB, 0x03D1, 0x03D7, 0x03DF, 0x03E5,
0x03F1, 0x03F5, 0x03FB, 0x03FD, 0x0407, 0x0409, 0x040F, 0x0419,
0x041B, 0x0425, 0x0427, 0x042D, 0x043F, 0x0443, 0x0445, 0x0449,
0x044F, 0x0455, 0x045D, 0x0463, 0x0469, 0x047F, 0x0481, 0x048B,
0x0493, 0x049D, 0x04A3, 0x04A9, 0x04B1, 0x04BD, 0x04C1, 0x04C7,
0x04CD, 0x04CF, 0x04D5, 0x04E1, 0x04EB, 0x04FD, 0x04FF, 0x0503,
0x0509, 0x050B, 0x0511, 0x0515, 0x0517, 0x051B, 0x0527, 0x0529,
0x052F, 0x0551, 0x0557, 0x055D, 0x0565, 0x0577, 0x0581, 0x058F,
0x0593, 0x0595, 0x0599, 0x059F, 0x05A7, 0x05AB, 0x05AD, 0x05B3,
0x05BF, 0x05C9, 0x05CB, 0x05CF, 0x05D1, 0x05D5, 0x05DB, 0x05E7,
0x05F3, 0x05FB, 0x0607, 0x060D, 0x0611, 0x0617, 0x061F, 0x0623,
0x062B, 0x062F, 0x063D, 0x0641, 0x0647, 0x0649, 0x064D, 0x0653 };
#define UPPER_LIMIT PRIME_SIZE
/* figures out if a number is prime (MR test) */
#ifdef CLEAN_STACK
static int _is_prime(mp_int *N, int *result)
#else
int is_prime(mp_int *N, int *result)
#endif
{
long x, s, j;
int res;
mp_int n1, a, y, r;
mp_digit d;
_ARGCHK(N != NULL);
_ARGCHK(result != NULL);
/* default to answer of no */
*result = 0;
/* divisible by any of the first primes? */
for (x = 0; x < (long)UPPER_LIMIT; x++) {
/* is N equal to a small prime? */
if (mp_cmp_d(N, prime_tab[x]) == 0) {
*result = 1;
return CRYPT_OK;
}
/* is N mod prime_tab[x] == 0, then its divisible by it */
if (mp_mod_d(N, prime_tab[x], &d) != MP_OKAY) {
return CRYPT_MEM;
}
if (d == 0) {
return CRYPT_OK;
}
}
/* init variables */
if (mp_init_multi(&r, &n1, &a, &y, NULL) != MP_OKAY) {
return CRYPT_MEM;
}
/* n1 = N - 1 */
if (mp_sub_d(N, 1, &n1) != MP_OKAY) { goto error; }
/* r = N - 1 */
if (mp_copy(&n1, &r) != MP_OKAY) { goto error; }
/* find s such that N-1 = (2^s)r */
s = 0;
while (mp_iseven(&r) != 0) {
++s;
if (mp_div_2(&r, &r) != MP_OKAY) {
goto error;
}
}
for (x = 0; x < 8; x++) {
/* choose a */
mp_set(&a, prime_tab[x]);
/* compute y = a^r mod n */
if (mp_exptmod(&a, &r, N, &y) != MP_OKAY) { goto error; }
/* (y != 1) AND (y != N-1) */
if ((mp_cmp_d(&y, 1) != 0) && (mp_cmp(&y, &n1) != 0)) {
/* while j <= s-1 and y != n-1 */
for (j = 1; (j <= (s-1)) && (mp_cmp(&y, &n1) != 0); j++) {
/* y = y^2 mod N */
if (mp_sqrmod(&y, N, &y) != MP_OKAY) { goto error; }
/* if y == 1 return false */
if (mp_cmp_d(&y, 1) == 0) { goto ok; }
}
/* if y != n-1 return false */
if (mp_cmp(&y, &n1) != 0) { goto ok; }
}
}
*result = 1;
ok:
res = CRYPT_OK;
goto done;
error:
res = CRYPT_MEM;
done:
mp_clear_multi(&a, &y, &n1, &r, NULL);
return res;
}
#ifdef CLEAN_STACK
int is_prime(mp_int *N, int *result)
{
int x;
x = _is_prime(N, result);
burn_stack(sizeof(long) * 3 + sizeof(int) + sizeof(mp_int) * 4 + sizeof(mp_digit));
return x;
}
#endif
int err;
if ((err = mp_prime_is_prime(N, 8, result)) != MP_OKAY) {
return CRYPT_MEM;
}
return CRYPT_OK;
}
static int next_prime(mp_int *N, mp_digit step)
{
@ -152,7 +25,7 @@ static int next_prime(mp_int *N, mp_digit step)
/* first find the residues */
for (x = 0; x < (long)UPPER_LIMIT; x++) {
if (mp_mod_d(N, prime_tab[x], &residues[x]) != MP_OKAY) {
if (mp_mod_d(N, __prime_tab[x], &residues[x]) != MP_OKAY) {
return CRYPT_MEM;
}
}
@ -168,7 +41,7 @@ loop:
dist = step;
for (x = 0; (dist < (MP_DIGIT_MAX-step-1)) && (x < (long)UPPER_LIMIT); x++) {
j = (long)residues[x] + (long)dist + total_dist;
if (j % (long)prime_tab[x] == 0) {
if (j % (long)__prime_tab[x] == 0) {
dist += step; x = -1;
}
}
@ -195,7 +68,7 @@ loop:
}
for (x = 0; x < 8; x++) {
/* choose a */
mp_set(&a, prime_tab[x]);
mp_set(&a, __prime_tab[x]);
/* compute y = a^r mod n */
if (mp_exptmod(&a, &r, N, &y) != MP_OKAY) { goto error; }

4
rc2.c
View File

@ -239,6 +239,9 @@ void rc2_ecb_decrypt( const unsigned char *cipher,
int rc2_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
int keylen;
unsigned char key[16], pt[8], ct[8];
@ -276,6 +279,7 @@ int rc2_test(void)
}
}
return CRYPT_OK;
#endif
}
int rc2_keysize(int *keysize)

4
rc5.c
View File

@ -152,6 +152,9 @@ void rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *
int rc5_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
unsigned char key[16], pt[8], ct[8];
} tests[] = {
@ -194,6 +197,7 @@ int rc5_test(void)
}
}
return CRYPT_OK;
#endif
}
int rc5_keysize(int *desired_keysize)

4
rc6.c
View File

@ -156,6 +156,9 @@ void rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *
int rc6_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
int keylen;
unsigned char key[32], pt[16], ct[16];
@ -214,6 +217,7 @@ int rc6_test(void)
}
}
return CRYPT_OK;
#endif
}
int rc6_keysize(int *desired_keysize)

87
rsa.c
View File

@ -5,7 +5,7 @@
int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key)
{
mp_int p, q, tmp1, tmp2, tmp3;
int res, err;
int res, err;
_ARGCHK(key != NULL);
@ -16,7 +16,7 @@ int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key)
if ((e < 3) || ((e & 1) == 0)) {
return CRYPT_INVALID_ARG;
}
if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
return err;
}
@ -34,7 +34,7 @@ int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key)
if (mp_sub_d(&p, 1, &tmp1) != MP_OKAY) { goto error; } /* tmp1 = p-1 */
if (mp_gcd(&tmp1, &tmp3, &tmp2) != MP_OKAY) { goto error; } /* tmp2 = gcd(p-1, e) */
} while (mp_cmp_d(&tmp2, 1) != 0); /* while e divides p-1 */
/* make prime "q" */
do {
if (rand_prime(&q, size/2, prng, wprng) != CRYPT_OK) { res = CRYPT_ERROR; goto done; }
@ -48,7 +48,7 @@ int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key)
if (mp_lcm(&tmp1, &tmp2, &tmp1) != MP_OKAY) { goto error; } /* tmp1 = lcm(p-1, q-1) */
/* make key */
if (mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP,
if (mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP,
&key->qP, &key->pQ, &key->p, &key->q, NULL) != MP_OKAY) {
goto error;
}
@ -64,16 +64,16 @@ int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key)
if (mp_mod(&key->d, &tmp1, &key->dP) != MP_OKAY) { goto error2; } /* dP = d mod p-1 */
if (mp_mod(&key->d, &tmp2, &key->dQ) != MP_OKAY) { goto error2; } /* dQ = d mod q-1 */
if (mp_invmod(&q, &p, &key->qP) != MP_OKAY) { goto error2; } /* qP = 1/q mod p */
if (mp_mulmod(&key->qP, &q, &key->N, &key->qP)) { goto error2; } /* qP = q * (1/q mod p) mod N */
if (mp_invmod(&p, &q, &key->pQ) != MP_OKAY) { goto error2; } /* pQ = 1/p mod q */
if (mp_invmod(&p, &q, &key->pQ) != MP_OKAY) { goto error2; } /* pQ = 1/p mod q */
if (mp_mulmod(&key->pQ, &p, &key->N, &key->pQ)) { goto error2; } /* pQ = p * (1/p mod q) mod N */
if (mp_copy(&p, &key->p) != MP_OKAY) { goto error2; }
if (mp_copy(&q, &key->q) != MP_OKAY) { goto error2; }
/* shrink ram required */
if (mp_shrink(&key->e) != MP_OKAY) { goto error2; }
if (mp_shrink(&key->d) != MP_OKAY) { goto error2; }
@ -84,12 +84,12 @@ int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key)
if (mp_shrink(&key->pQ) != MP_OKAY) { goto error2; }
if (mp_shrink(&key->p) != MP_OKAY) { goto error2; }
if (mp_shrink(&key->q) != MP_OKAY) { goto error2; }
res = CRYPT_OK;
key->type = PK_PRIVATE_OPTIMIZED;
goto done;
error2:
mp_clear_multi(&key->d, &key->e, &key->N, &key->dQ, &key->dP,
mp_clear_multi(&key->d, &key->e, &key->N, &key->dQ, &key->dP,
&key->qP, &key->pQ, &key->p, &key->q, NULL);
error:
res = CRYPT_MEM;
@ -101,7 +101,7 @@ done:
void rsa_free(rsa_key *key)
{
_ARGCHK(key != NULL);
mp_clear_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP,
mp_clear_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP,
&key->qP, &key->pQ, &key->p, &key->q, NULL);
}
@ -125,7 +125,7 @@ int rsa_exptmod(const unsigned char *in, unsigned long inlen,
/* init and copy into tmp */
if (mp_init_multi(&tmp, &tmpa, &tmpb, NULL) != MP_OKAY) { goto error; }
if (mp_read_unsigned_bin(&tmp, (unsigned char *)in, (int)inlen) != MP_OKAY) { goto error; }
/* sanity check on the input */
if (mp_cmp(&key->N, &tmp) == MP_LT) {
res = CRYPT_PK_INVALID_SIZE;
@ -158,7 +158,7 @@ int rsa_exptmod(const unsigned char *in, unsigned long inlen,
*outlen = x;
/* convert it */
(void)mp_to_unsigned_bin(&tmp, out);
if (mp_to_unsigned_bin(&tmp, out) != MP_OKAY) { goto error; }
/* clean up and return */
res = CRYPT_OK;
@ -170,7 +170,7 @@ done:
return res;
}
int rsa_signpad(const unsigned char *in, unsigned long inlen,
int rsa_signpad(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen)
{
unsigned long x, y;
@ -184,10 +184,10 @@ int rsa_signpad(const unsigned char *in, unsigned long inlen,
}
/* check inlen */
if ((inlen <= 0) || inlen > 512) {
if (inlen > 512) {
return CRYPT_PK_INVALID_SIZE;
}
for (y = x = 0; x < inlen; x++)
out[y++] = (unsigned char)0xFF;
for (x = 0; x < inlen; x++)
@ -198,8 +198,8 @@ int rsa_signpad(const unsigned char *in, unsigned long inlen,
return CRYPT_OK;
}
int rsa_pad(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen,
int rsa_pad(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen,
int wprng, prng_state *prng)
{
unsigned char buf[1536];
@ -211,17 +211,17 @@ int rsa_pad(const unsigned char *in, unsigned long inlen,
_ARGCHK(outlen != NULL);
/* is output big enough? */
if (*outlen < (3 * inlen)) {
if (*outlen < (3 * inlen)) {
return CRYPT_BUFFER_OVERFLOW;
}
/* get random padding required */
if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
return err;
return err;
}
/* check inlen */
if ((inlen <= 0) || inlen > 512) {
if (inlen > 512) {
return CRYPT_PK_INVALID_SIZE;
}
@ -229,14 +229,14 @@ int rsa_pad(const unsigned char *in, unsigned long inlen,
return CRYPT_ERROR_READPRNG;
}
/* pad it like a sandwitch (sp?)
/* pad it like a sandwhich
*
* Looks like 0xFF R1 M R2 0xFF
*
* Where R1/R2 are random and exactly equal to the length of M minus one byte.
*
* Where R1/R2 are random and exactly equal to the length of M minus one byte.
*/
for (x = 0; x < inlen-1; x++) {
out[x+1] = buf[x];
for (x = 0; x < inlen-1; x++) {
out[x+1] = buf[x];
}
for (x = 0; x < inlen; x++) {
@ -258,7 +258,7 @@ int rsa_pad(const unsigned char *in, unsigned long inlen,
return CRYPT_OK;
}
int rsa_signdepad(const unsigned char *in, unsigned long inlen,
int rsa_signdepad(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen)
{
unsigned long x;
@ -267,7 +267,7 @@ int rsa_signdepad(const unsigned char *in, unsigned long inlen,
_ARGCHK(out != NULL);
_ARGCHK(outlen != NULL);
if (*outlen < inlen/3) {
if (*outlen < inlen/3) {
return CRYPT_BUFFER_OVERFLOW;
}
@ -277,13 +277,13 @@ int rsa_signdepad(const unsigned char *in, unsigned long inlen,
return CRYPT_INVALID_PACKET;
}
}
for (x = 0; x < inlen/3; x++)
for (x = 0; x < inlen/3; x++)
out[x] = in[x+(inlen/3)];
*outlen = inlen/3;
return CRYPT_OK;
}
int rsa_depad(const unsigned char *in, unsigned long inlen,
int rsa_depad(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen)
{
unsigned long x;
@ -292,10 +292,10 @@ int rsa_depad(const unsigned char *in, unsigned long inlen,
_ARGCHK(out != NULL);
_ARGCHK(outlen != NULL);
if (*outlen < inlen/3) {
if (*outlen < inlen/3) {
return CRYPT_BUFFER_OVERFLOW;
}
for (x = 0; x < inlen/3; x++)
for (x = 0; x < inlen/3; x++)
out[x] = in[x+(inlen/3)];
*outlen = inlen/3;
return CRYPT_OK;
@ -350,8 +350,8 @@ int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key
_ARGCHK(key != NULL);
/* type valid? */
if (!(key->type == PK_PRIVATE || key->type == PK_PRIVATE_OPTIMIZED) &&
(type == PK_PRIVATE || type == PK_PRIVATE_OPTIMIZED)) {
if (!(key->type == PK_PRIVATE || key->type == PK_PRIVATE_OPTIMIZED) &&
(type == PK_PRIVATE || type == PK_PRIVATE_OPTIMIZED)) {
return CRYPT_PK_INVALID_TYPE;
}
@ -363,7 +363,7 @@ int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key
/* output modulus */
OUTPUT_BIGNUM(&key->N, buf2, y, z);
/* output public key */
OUTPUT_BIGNUM(&key->e, buf2, y, z);
@ -381,7 +381,7 @@ int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key
}
/* check size */
if (*outlen < y) {
if (*outlen < y) {
return CRYPT_BUFFER_OVERFLOW;
}
@ -407,17 +407,18 @@ int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key)
_ARGCHK(in != NULL);
_ARGCHK(key != NULL);
/* test packet header */
if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_RSA, PACKET_SUB_KEY)) != CRYPT_OK) {
return err;
}
/* check length */
if (inlen < 1+PACKET_SIZE) {
return CRYPT_INVALID_PACKET;
}
/* test packet header */
if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_RSA, PACKET_SUB_KEY)) != CRYPT_OK) {
return err;
}
/* init key */
if (mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, &key->qP,
if (mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, &key->qP,
&key->pQ, &key->p, &key->q, NULL) != MP_OKAY) {
return CRYPT_MEM;
}
@ -446,7 +447,7 @@ int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key)
INPUT_BIGNUM(&key->p, in, x, y);
INPUT_BIGNUM(&key->q, in, x, y);
}
/* free up ram not required */
if (key->type != PK_PRIVATE_OPTIMIZED) {
mp_clear_multi(&key->dQ, &key->dP, &key->pQ, &key->qP, &key->p, &key->q, NULL);
@ -457,7 +458,7 @@ int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key)
return CRYPT_OK;
error2:
mp_clear_multi(&key->d, &key->e, &key->N, &key->dQ, &key->dP,
mp_clear_multi(&key->d, &key->e, &key->N, &key->dQ, &key->dP,
&key->pQ, &key->qP, &key->p, &key->q, NULL);
return err;
}

View File

@ -69,7 +69,7 @@ int rsa_decrypt_key(const unsigned char *in, unsigned long inlen,
unsigned char *outkey, unsigned long *keylen,
rsa_key *key)
{
unsigned char sym_key[MAXBLOCKSIZE], rsa_in[4096], rsa_out[4096];
unsigned char sym_key[MAXBLOCKSIZE], rsa_out[4096];
unsigned long x, y, z, i, rsa_size;
int err;
@ -129,7 +129,6 @@ int rsa_decrypt_key(const unsigned char *in, unsigned long inlen,
#ifdef CLEAN_STACK
/* clean up */
zeromem(sym_key, sizeof(sym_key));
zeromem(rsa_in, sizeof(rsa_in));
zeromem(rsa_out, sizeof(rsa_out));
#endif
*keylen = z;
@ -150,7 +149,7 @@ int rsa_sign_hash(const unsigned char *in, unsigned long inlen,
_ARGCHK(key != NULL);
/* reject nonsense sizes */
if (inlen < 16) {
if (inlen > MAXBLOCKSIZE || inlen < 16) {
return CRYPT_INVALID_ARG;
}

View File

@ -407,6 +407,9 @@ void saferp_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_ke
int saferp_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
int keylen;
unsigned char key[32], pt[16], ct[16];
@ -459,6 +462,7 @@ int saferp_test(void)
}
return CRYPT_OK;
#endif
}
int saferp_keysize(int *desired_keysize)

16
safer.c
View File

@ -344,6 +344,9 @@ int safer_128_keysize(int *keysize)
int safer_k64_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const unsigned char k64_pt[] = { 1, 2, 3, 4, 5, 6, 7, 8 },
k64_key[] = { 8, 7, 6, 5, 4, 3, 2, 1 },
k64_ct[] = { 200, 242, 156, 221, 135, 120, 62, 217 };
@ -364,11 +367,15 @@ int safer_k64_test(void)
}
return CRYPT_OK;
#endif
}
int safer_sk64_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const unsigned char sk64_pt[] = { 1, 2, 3, 4, 5, 6, 7, 8 },
sk64_key[] = { 1, 2, 3, 4, 5, 6, 7, 8 },
sk64_ct[] = { 95, 206, 155, 162, 5, 132, 56, 199 };
@ -390,10 +397,14 @@ int safer_sk64_test(void)
}
return CRYPT_OK;
#endif
}
int safer_sk128_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const unsigned char sk128_pt[] = { 1, 2, 3, 4, 5, 6, 7, 8 },
sk128_key[] = { 1, 2, 3, 4, 5, 6, 7, 8,
0, 0, 0, 0, 0, 0, 0, 0 },
@ -413,9 +424,8 @@ int safer_sk128_test(void)
if (memcmp(buf[0], sk128_ct, 8) != 0 || memcmp(buf[1], sk128_pt, 8) != 0) {
return CRYPT_FAIL_TESTVECTOR;
}
return CRYPT_OK;
return CRYPT_OK;
#endif
}
#endif

View File

@ -588,6 +588,9 @@ void serpent_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_k
int serpent_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
int keylen;
unsigned char key[32], pt[16], ct[16];
@ -680,6 +683,7 @@ int serpent_test(void)
}
}
return CRYPT_OK;
#endif
}
int serpent_keysize(int *desired_keysize)

4
sha1.c
View File

@ -184,6 +184,9 @@ void sha1_done(hash_state * md, unsigned char *hash)
int sha1_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
char *msg;
unsigned char hash[20];
@ -213,6 +216,7 @@ int sha1_test(void)
}
}
return CRYPT_OK;
#endif
}
#endif

View File

@ -34,8 +34,8 @@ static const unsigned long K[64] = {
/* Various logical functions */
#define Ch(x,y,z) ((x & y) | (~x & z))
#define Maj(x,y,z) (((x | y) & z) | (x & y))
#define S(x, n) ROR((x),(n))
#define R(x, n) (((x)&0xFFFFFFFFUL)>>(n))
#define S(x, n) ROR((x),(n))
#define R(x, n) (((x)&0xFFFFFFFFUL)>>(n))
#define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22))
#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25))
#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3))
@ -180,6 +180,9 @@ void sha256_done(hash_state * md, unsigned char *hash)
int sha256_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
char *msg;
unsigned char hash[32];
@ -211,6 +214,7 @@ int sha256_test(void)
}
}
return CRYPT_OK;
#endif
}
#endif

View File

@ -51,6 +51,9 @@ void sha384_done(hash_state * md, unsigned char *hash)
int sha384_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
char *msg;
unsigned char hash[48];
@ -86,6 +89,7 @@ int sha384_test(void)
}
}
return CRYPT_OK;
#endif
}

View File

@ -209,6 +209,9 @@ void sha512_done(hash_state * md, unsigned char *hash)
int sha512_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
char *msg;
unsigned char hash[64];
@ -248,6 +251,7 @@ int sha512_test(void)
}
}
return CRYPT_OK;
#endif
}
#ifdef SHA384

View File

@ -687,6 +687,9 @@ void tiger_done(hash_state * md, unsigned char *hash)
int tiger_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
char *msg;
unsigned char hash[24];
@ -731,6 +734,7 @@ int tiger_test(void)
}
}
return CRYPT_OK;
#endif
}
#endif

141
tommath.h
View File

@ -1,19 +1,17 @@
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
* LibTomMath is library that provides for multiple-precision
* LibTomMath is library that provides for multiple-precision
* integer arithmetic as well as number theoretic functionality.
*
*
* The library is designed directly after the MPI library by
* Michael Fromberger but has been written from scratch with
* additional optimizations in place.
* Michael Fromberger but has been written from scratch with
* additional optimizations in place.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/
#include <mycrypt.h>
#ifndef BN_H_
#define BN_H_
@ -36,18 +34,18 @@ extern "C" {
#else
/* C on the other hand dosen't care */
#define OPT_CAST
/* C on the other hand doesn't care */
#define OPT_CAST
#endif
/* some default configurations.
/* some default configurations.
*
* A "mp_digit" must be able to hold DIGIT_BIT + 1 bits
* A "mp_word" must be able to hold 2*DIGIT_BIT + 1 bits
* A "mp_digit" must be able to hold DIGIT_BIT + 1 bits
* A "mp_word" must be able to hold 2*DIGIT_BIT + 1 bits
*
* At the very least a mp_digit must be able to hold 7 bits
* [any size beyond that is ok provided it overflow the data type]
* At the very least a mp_digit must be able to hold 7 bits
* [any size beyond that is ok provided it doesn't overflow the data type]
*/
#ifdef MP_8BIT
typedef unsigned char mp_digit;
@ -55,31 +53,50 @@ extern "C" {
#elif defined(MP_16BIT)
typedef unsigned short mp_digit;
typedef unsigned long mp_word;
#else
#elif defined(MP_64BIT)
/* for GCC only on supported platforms */
#ifndef CRYPT
#ifdef _MSC_VER
typedef unsigned long long ulong64;
typedef signed long long long64;
#endif
typedef ulong64 mp_digit;
typedef unsigned long mp_word __attribute__ ((mode(TI)));
#define DIGIT_BIT 60
#else
/* this is the default case, 28-bit digits */
/* this is to make porting into LibTomCrypt easier :-) */
#ifndef CRYPT
#if defined(_MSC_VER) || defined(__BORLANDC__)
typedef unsigned __int64 ulong64;
typedef signed __int64 long64;
#else
typedef unsigned long long ulong64;
typedef signed long long long64;
#endif
#endif
#endif
#endif
/* default case */
typedef unsigned long mp_digit;
typedef ulong64 mp_word;
#define DIGIT_BIT 28
#endif
#ifdef MP_31BIT
#define DIGIT_BIT 31
#else
#define DIGIT_BIT 28
#endif
#endif
/* otherwise the bits per digit is calculated automatically from the size of a mp_digit */
#ifndef DIGIT_BIT
#define DIGIT_BIT ((CHAR_BIT * sizeof(mp_digit) - 1)) /* bits per digit */
#endif
#define MP_DIGIT_BIT DIGIT_BIT
#define MP_MASK ((((mp_digit)1)<<((mp_digit)DIGIT_BIT))-((mp_digit)1))
#define MP_DIGIT_MAX MP_MASK
#define MP_DIGIT_MAX MP_MASK
/* equalities */
#define MP_LT -1 /* less than */
@ -99,9 +116,17 @@ typedef int mp_err;
/* you'll have to tune these... */
extern int KARATSUBA_MUL_CUTOFF,
KARATSUBA_SQR_CUTOFF,
MONTGOMERY_EXPT_CUTOFF;
TOOM_MUL_CUTOFF,
TOOM_SQR_CUTOFF;
#define MP_PREC 64 /* default digits of precision */
/* various build options */
#define MP_PREC 64 /* default digits of precision (must be power of two) */
/* define this to use lower memory usage routines (exptmods mostly) */
/* #define MP_LOW_MEM */
/* size of comba arrays, should be at least 2 * 2**(BITS_PER_WORD - BITS_PER_DIGIT*2) */
#define MP_WARRAY (1 << (sizeof(mp_word) * CHAR_BIT - 2 * DIGIT_BIT + 1))
typedef struct {
int used, alloc, sign;
@ -120,6 +145,12 @@ int mp_init(mp_int *a);
/* free a bignum */
void mp_clear(mp_int *a);
/* init a null terminated series of arguments */
int mp_init_multi(mp_int *mp, ...);
/* clear a null terminated series of arguments */
void mp_clear_multi(mp_int *mp, ...);
/* exchange two ints */
void mp_exch(mp_int *a, mp_int *b);
@ -145,7 +176,7 @@ void mp_zero(mp_int *a);
void mp_set(mp_int *a, mp_digit b);
/* set a 32-bit const */
int mp_set_int(mp_int *a, unsigned long b);
int mp_set_int(mp_int *a, unsigned int b);
/* copy, b = a */
int mp_copy(mp_int *a, mp_int *b);
@ -164,22 +195,22 @@ void mp_rshd(mp_int *a, int b);
/* left shift by "b" digits */
int mp_lshd(mp_int *a, int b);
/* c = a / 2^b */
/* c = a / 2**b */
int mp_div_2d(mp_int *a, int b, mp_int *c, mp_int *d);
/* b = a/2 */
int mp_div_2(mp_int *a, mp_int *b);
/* c = a * 2^b */
/* c = a * 2**b */
int mp_mul_2d(mp_int *a, int b, mp_int *c);
/* b = a*2 */
int mp_mul_2(mp_int *a, mp_int *b);
/* c = a mod 2^d */
/* c = a mod 2**d */
int mp_mod_2d(mp_int *a, int b, mp_int *c);
/* computes a = 2^b */
/* computes a = 2**b */
int mp_2expt(mp_int *a, int b);
/* makes a pseudo-random int of a given size */
@ -218,7 +249,7 @@ int mp_sub(mp_int *a, mp_int *b, mp_int *c);
/* c = a * b */
int mp_mul(mp_int *a, mp_int *b, mp_int *c);
/* b = a^2 */
/* b = a*a */
int mp_sqr(mp_int *a, mp_int *b);
/* a/b => cb + d == a */
@ -244,7 +275,10 @@ int mp_mul_d(mp_int *a, mp_digit b, mp_int *c);
/* a/b => cb + d == a */
int mp_div_d(mp_int *a, mp_digit b, mp_int *c, mp_digit *d);
/* c = a^b */
/* a/3 => 3c + d == a */
int mp_div_3(mp_int *a, mp_int *c, mp_digit *d);
/* c = a**b */
int mp_expt_d(mp_int *a, mp_digit b, mp_int *c);
/* c = a mod b, 0 <= c < b */
@ -273,7 +307,7 @@ int mp_gcd(mp_int *a, mp_int *b, mp_int *c);
/* c = [a, b] or (a*b)/(a, b) */
int mp_lcm(mp_int *a, mp_int *b, mp_int *c);
/* finds one of the b'th root of a, such that |c|^b <= |a|
/* finds one of the b'th root of a, such that |c|**b <= |a|
*
* returns error if a < 0 and b is even
*/
@ -290,7 +324,7 @@ int mp_reduce_setup(mp_int *a, mp_int *b);
/* Barrett Reduction, computes a (mod b) with a precomputed value c
*
* Assumes that 0 < a <= b^2, note if 0 > a > -(b^2) then you can merely
* Assumes that 0 < a <= b*b, note if 0 > a > -(b*b) then you can merely
* compute the reduction as -1 * mp_reduce(mp_abs(a)) [pseudo code].
*/
int mp_reduce(mp_int *a, mp_int *b, mp_int *c);
@ -298,12 +332,12 @@ int mp_reduce(mp_int *a, mp_int *b, mp_int *c);
/* setups the montgomery reduction */
int mp_montgomery_setup(mp_int *a, mp_digit *mp);
/* computes a = B^n mod b without division or multiplication useful for
/* computes a = B**n mod b without division or multiplication useful for
* normalizing numbers in a Montgomery system.
*/
int mp_montgomery_calc_normalization(mp_int *a, mp_int *b);
/* computes xR^-1 == x (mod N) via Montgomery Reduction */
/* computes x/R == 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 */
@ -315,32 +349,47 @@ 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) */
/* returns true if a can be reduced with mp_reduce_2k */
int mp_reduce_is_2k(mp_int *a);
/* determines k value for 2k reduction */
int mp_reduce_2k_setup(mp_int *a, mp_digit *d);
/* reduces a modulo b where b is of the form 2**p - k [0 <= a] */
int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit k);
/* 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 */
/* number of primes */
#ifdef MP_8BIT
#define PRIME_SIZE 31
#else
#define PRIME_SIZE 256
#endif
/* table of first PRIME_SIZE primes */
extern const mp_digit __prime_tab[];
/* result=1 if a is divisible by one of the first 256 primes */
/* result=1 if a is divisible by one of the first PRIME_SIZE 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
/* 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
* 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.
* of error no more than (1/4)**t.
*
* Sets result to 1 if probably prime, 0 otherwise
*/
@ -367,6 +416,9 @@ int mp_read_radix(mp_int *a, char *str, int radix);
int mp_toradix(mp_int *a, char *str, int radix);
int mp_radix_size(mp_int *a, int radix);
int mp_fread(mp_int *a, int radix, FILE *stream);
int mp_fwrite(mp_int *a, int radix, FILE *stream);
#define mp_read_raw(mp, str, len) mp_read_signed_bin((mp), (str), (len))
#define mp_raw_size(mp) mp_signed_bin_size(mp)
#define mp_toraw(mp, str) mp_to_signed_bin((mp), (str))
@ -390,10 +442,13 @@ int s_mp_mul_high_digs(mp_int *a, mp_int *b, mp_int *c, int digs);
int fast_s_mp_sqr(mp_int *a, mp_int *b);
int s_mp_sqr(mp_int *a, mp_int *b);
int mp_karatsuba_mul(mp_int *a, mp_int *b, mp_int *c);
int mp_toom_mul(mp_int *a, mp_int *b, mp_int *c);
int mp_karatsuba_sqr(mp_int *a, mp_int *b);
int mp_toom_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 mode);
int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y);
void bn_reverse(unsigned char *s, int len);
#ifdef __cplusplus

View File

@ -633,6 +633,9 @@ void twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_k
int twofish_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
int keylen;
unsigned char key[32], pt[16], ct[16];
@ -682,6 +685,7 @@ int twofish_test(void)
}
}
return CRYPT_OK;
#endif
}
int twofish_keysize(int *desired_keysize)

4
xtea.c
View File

@ -107,6 +107,9 @@ void xtea_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key
int xtea_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const unsigned char key[16] =
{ 0x78, 0x56, 0x34, 0x12, 0xf0, 0xcd, 0xcb, 0x9a,
0x48, 0x37, 0x26, 0x15, 0xc0, 0xbf, 0xae, 0x9d };
@ -129,6 +132,7 @@ int xtea_test(void)
}
return CRYPT_OK;
#endif
}
int xtea_keysize(int *desired_keysize)