added libtomcrypt-0.84
This commit is contained in:
parent
90a48a5bec
commit
d6071c6267
4
aes.c
4
aes.c
@ -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
55
ampi.c
@ -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
|
||||
|
@ -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)
|
||||
|
4
cast5.c
4
cast5.c
@ -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
11
changes
@ -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
|
||||
|
@ -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";
|
||||
|
47
crypt.tex
47
crypt.tex
@ -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,
|
||||
|
182
demos/test.c
182
demos/test.c
@ -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
8
des.c
@ -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
48
dh.c
@ -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;
|
||||
|
19
dh_sys.c
19
dh_sys.c
@ -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
166
ecc.c
@ -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;
|
||||
|
14
ecc_sys.c
14
ecc_sys.c
@ -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
6
hmac.c
@ -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
|
||||
|
11
makefile
11
makefile
@ -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
|
||||
|
@ -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
4
md2.c
@ -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
4
md4.c
@ -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
4
md5.c
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
147
prime.c
@ -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
4
rc2.c
@ -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
4
rc5.c
@ -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
4
rc6.c
@ -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
87
rsa.c
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
4
safer+.c
4
safer+.c
@ -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
16
safer.c
@ -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
|
||||
|
@ -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
4
sha1.c
@ -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
|
||||
|
8
sha256.c
8
sha256.c
@ -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
|
||||
|
4
sha384.c
4
sha384.c
@ -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
|
||||
}
|
||||
|
||||
|
||||
|
4
sha512.c
4
sha512.c
@ -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
|
||||
|
4
tiger.c
4
tiger.c
@ -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
141
tommath.h
@ -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
|
||||
|
@ -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
4
xtea.c
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user