added libtomcrypt-0.90

This commit is contained in:
Tom St Denis 2003-09-08 01:06:11 +00:00 committed by Steffen Jaeckel
parent 710106cda5
commit 16100c38eb
24 changed files with 1687 additions and 591 deletions

28
changes
View File

@ -1,3 +1,31 @@
Sept 7th, 2003
v0.90 -- new ROL/ROR for x86 GCC
-- Jochen Katz submitted a patch to the makefile to prevent "make" from making the .a library
when not required.
== By default the KR code is not enabled [it's only a demo anyways!]
-- changed the "buf" in ecc_make_key from 4KB to 128 bytes [since the largest key is 65 bytes]
-- hmac_done() now requires you pass it the size of the destination buffer to prevent
buffer overflows. (API CHANGE)
-- hmac/hash filebased routines now return CRYPT_NOP if NO_FILE is defined.
-- I've removed the primes from dh.c and replaced them with DR safe primes suitable for the default
configuration of LibTomMath. Check out these comparisons on a 1.3Ghz Athlon XP, optimized for size,
768-bit, 4 vs. 10
1024-bit, 8 vs. 18
1280-bit, 12 vs. 34
1536-bit, 20 vs. 56
1792-bit 28 vs. 88
2048-bit, 40 vs. 124
2560-bit, 71 vs. 234
3072-bit, 113 vs. 386
4096-bit, 283 vs. 916
Times are all in milliseconds for key generation. New primes times on the left. This makes the code binary
incompatible with previous releases. However, this addition is long overdue as LibTomMath has supported DR
reductions for quite some time.
-- Added RIPE-MD 128 and 160 to the list of supported hashes [10 in total].
-- The project has been released as public domain. TDCAL no longer applies.
July 15th, 2003
v0.89 -- Fix a bug in bits.c which would prevent it from building with msvc
-- Merged in LibTomMath v0.24 [and I used the alloc/free macros this time!]

View File

@ -21,7 +21,7 @@
);
@opts = (
"SMALL_CODE,Use small code where possible (slower code),n",
"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",
@ -55,6 +55,8 @@
"MD5,Include MD5 one-way hash,y",
"MD4,Include MD4 one-way hash,y",
"MD2,Include MD2 one-way hash,y",
"RIPEMD128,Include RIPEMD-128 one-way hash,y",
"RIPEMD160,Include RIPEMD-160 one-way hash,y",
"HMAC,Include Hash based Message Authentication Support,y",
"BASE64,Include Base64 encoding support,y",
@ -68,7 +70,7 @@
"MRSA,Include RSA public key support,y",
"MDH,Include Diffie-Hellman (over Z/pZ) public key support,y",
"MECC,Include Eliptic Curve public key crypto support,y",
"KR,Include Keyring support (groups all three PK systems),y",
"KR,Include Keyring support (groups all three PK systems),n",
"DH768,768-bit DH key support,y",
"DH1024,1024-bit DH key support,y",

View File

@ -443,6 +443,9 @@ const char *crypt_build_settings =
#if defined(MD2)
" MD2\n"
#endif
#if defined(RIPEMD128)
" RIPEMD128\n"
#endif
"\nBlock Chaining Modes:\n"
#if defined(CFB)

BIN
crypt.pdf

Binary file not shown.

View File

@ -47,7 +47,7 @@
\def\gap{\vspace{0.5ex}}
\makeindex
\begin{document}
\title{A Tiny Crypto Library, \\ LibTomCrypt \\ Version 0.89}
\title{A Tiny Crypto Library, \\ LibTomCrypt \\ Version 0.90}
\author{Tom St Denis \\
Algonquin College \\
\\
@ -158,25 +158,20 @@ can make use of the cipher right away.
\section{License}
All of the source code except for the following files have been written by the author or donated to the project
under the TDCAL license:
under a public domain license:
\begin{enumerate}
\item rc2.c
\item safer.c
\end{enumerate}
`mpi.c'' was originally written
by Michael Fromberger (sting@linguist.dartmouth.edu) but has since been replaced with my LibTomMath library.
``rc2.c'' is based on publicly available code that is not attributed to a person from the given source. ``safer.c''
`mpi.c'' was originally written by Michael Fromberger (sting@linguist.dartmouth.edu) but has since been replaced with my LibTomMath
library.
``rc2.c'' is based on publicly available code that is not attributed to a person from the given source. ``safer.c''
was written by Richard De Moliner (demoliner@isi.ee.ethz.ch) and is public domain.
The rest of the code was written either by Tom St Denis or contributed to the project under the ``Tom Doesn't Care
About Licenses'' (TDCAL) license. Essentially this license grants the user unlimited distribution and usage (including
commercial usage). This means that you can use the package, you can re-distribute the package and even branch it. I
still retain ownership over the name of the package. If you want to branch the project you can use the code as a base
but you must change the name. The package is also royalty free which means you can use it in commercial products
without compensation towards the author. I assume no risk from usage of the code nor do I guarantee it works as
desired or stated.
The project is hereby released as public domain.
\section{Patent Disclosure}
@ -364,7 +359,7 @@ have the same prototype and store their keys as naturally as possible. All cip
are (given that XXX is the name of the cipher):
\index{Cipher Setup}
\begin{verbatim}
int XXX_setup(const unsigned char *key, int keylen, int rounds,
int XXX_setup(const unsigned char *key, int keylen, int rounds,
symmetric_key *skey);
\end{verbatim}
@ -973,6 +968,8 @@ The following hashes are provided as of this release:
\hline SHA-256 & sha256\_desc & 32 \\
\hline TIGER-192 & tiger\_desc & 24 \\
\hline SHA-1 & sha1\_desc & 20 \\
\hline RIPEMD-160 & rmd160\_desc & 20 \\
\hline RIPEMD-128 & rmd128\_desc & 16 \\
\hline MD5 & md5\_desc & 16 \\
\hline MD4 & md4\_desc & 16 \\
\hline MD2 & md2\_desc & 16 \\
@ -1019,10 +1016,12 @@ int hmac_process(hmac_state *hmac, const unsigned char *buf,
number of octets to process. Like the hash process routines you can send the data in arbitrarly sized chunks. When you
are finished with the HMAC process you must call the following function to get the HMAC code:
\begin{verbatim}
int hmac_done(hmac_state *hmac, unsigned char *hash);
int hmac_done(hmac_state *hmac, unsigned char *hashOut,
unsigned long *outlen);
\end{verbatim}
``hmac'' is the HMAC state you are working with. ``hash'' is the array of octets where the HMAC code should be stored. You
must ensure that your destination array is the right size (or just make it of size MAXBLOCKSIZE to be sure).
``hmac'' is the HMAC state you are working with. ``hashOut'' is the array of octets where the HMAC code should be stored. You must
set ``outlen'' to the size of the destination buffer before calling this function. It is updated with the length of the HMAC code
produced (depending on which hash was picked)
There are two utility functions provided to make using HMACs easier todo. They accept the key and information about the
message (file pointer, address in memory) and produce the HMAC result in one shot. These are useful if you want to avoid
@ -1061,6 +1060,7 @@ int main(void)
int idx, errno;
hmac_state hmac;
unsigned char key[16], dst[MAXBLOCKSIZE];
unsigned long dstlen;
/* register SHA-1 */
if (register_hash(&sha1_desc) == -1) {
@ -1086,10 +1086,12 @@ int main(void)
}
/* get result (presumably to use it somehow...) */
if ((errno = hmac_done(&hmac, dst)) != CRYPT_OK) {
dstlen = sizeof(dst);
if ((errno = hmac_done(&hmac, dst, &dstlen)) != CRYPT_OK) {
printf("Error finishing hmac: %s\n", error_to_string(errno));
return -1;
}
printf("The hmac is %lu bytes long\n", dstlen);
/* return */
return 0;

View File

@ -89,7 +89,7 @@ store_tests (void)
L = 0;
LOAD32H (L, &buf[0]);
if (L != 0x12345678UL) {
printf ("LOAD/STORE32 High don't work\n");
printf ("LOAD/STORE32 High don't work, %08lx\n", L);
exit (-1);
}
LL = CONST64 (0x01020304050607);
@ -839,7 +839,12 @@ 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)); */
printf("Testing builting DH parameters...."); fflush(stdout);
if ((errnum = dh_test()) != CRYPT_OK) {
printf("DH Error: %s\n", error_to_string(errnum));
exit(-1);
}
printf("Passed.\n");
dh_sizes (&low, &high);
printf ("DH Keys from %d to %d supported.\n", low * 8, high * 8);
@ -916,13 +921,13 @@ dh_tests (void)
for (ii = 0; ii < (int) (sizeof (sizes) / sizeof (sizes[0])); ii++) {
t1 = XCLOCK ();
for (tt = 0; tt < 5; tt++) {
for (tt = 0; tt < 25; tt++) {
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 / 25.0) / (double) XCLOCKS_PER_SEC));
}
}
@ -1359,6 +1364,12 @@ register_all_algs (void)
#ifdef SHA512
register_hash (&sha512_desc);
#endif
#ifdef RIPEMD128
register_hash (&rmd128_desc);
#endif
#ifdef RIPEMD160
register_hash (&rmd160_desc);
#endif
#ifdef YARROW
register_prng (&yarrow_desc);
@ -1713,7 +1724,7 @@ main (void)
if ((errnum = yarrow_start (&prng)) != CRYPT_OK) {
printf ("yarrow_start: %s\n", error_to_string (errnum));
}
if ((errnum = yarrow_add_entropy ("hello", 5, &prng)) != CRYPT_OK) {
if ((errnum = yarrow_add_entropy ((unsigned char *)"hello", 5, &prng)) != CRYPT_OK) {
printf ("yarrow_add_entropy: %s\n", error_to_string (errnum));
}
if ((errnum = yarrow_ready (&prng)) != CRYPT_OK) {
@ -1742,7 +1753,7 @@ main (void)
#ifdef KR
kr_test ();
#endif
#endif
rsa_test ();
pad_test ();
ecc_tests ();

View File

@ -132,6 +132,9 @@ void reg_algs(void)
#ifdef SHA512
register_hash (&sha512_desc);
#endif
#ifdef RIPEMD128
register_hash (&rmd128_desc);
#endif
}

128
dh.c
View File

@ -11,118 +11,118 @@ static const struct {
{
96,
"DH-768",
"2",
"1tH+dRFGpEYyVLe4ydZcYyGDpeAxnChz0yk+pNCtkEXwUsOORyguBtx8spUD"
"FAjEDS8PutUBTEu2q4USqu19dUbCLj9D2jY7y3871RnSccurMBsMm35ILcyQ"
"rpN0MQKc/"
"4",
"F///////////////////////////////////////////////////////////"
"////////////////////////////////////////////////////////////"
"//////m3wvV"
},
#endif
#ifdef DH1024
{
128,
"DH-1024",
"2",
"Uypu+t9nfUnCj7xD+xokM+Cd6mASW4ofg1jpC2BpQasC5edtA1dJC+RjbOBZ"
"z+5mvq5VYT8Wfjmlpjm9tQxHOYB0+3Myl7gbCQ5SRljWT2oBLukLNvgFjiU4"
"wiWkmu41Ern/j6uxwKb740C+VIgDAdeUY4fA5hyfr3/+DWYb14/"
"4",
"F///////////////////////////////////////////////////////////"
"////////////////////////////////////////////////////////////"
"////////////////////////////////////////////////m3C47"
},
#endif
#ifdef DH1280
{
160,
"DH-1280",
"2",
"520QV4Tsq4NwK9Mt5CGR9xk4slvaikgi/ax3OPky5GERKTsoqEXOlFyMzURP"
"P8jYzCVz1izKd2zTDxbFfLxrJry0ceaQ5YZa5N4teByCPVlQh4v6iQl+944+"
"/NDlKzvWpx7HG7k8cGKhva7aFF8bP/CvLpaQhrfXlOX+X9pcmML9QH63tUjq"
"B80l8Yx9KN0dC3iNnsTV3DnqnEvFQkoqql"
"4",
"F///////////////////////////////////////////////////////////"
"////////////////////////////////////////////////////////////"
"////////////////////////////////////////////////////////////"
"//////////////////////////////m4kSN"
},
#endif
#ifdef DH1536
{
192,
"DH-1536",
"3",
"1FTWXrPcY1w74oZ0ouIzSN8uZcRiOf6U11fx0ka6+7fqIAezPhd3Ab43QnDf"
"KFg+or/fFRGEWAxF8WIE2jx8iTOu010yNEQyH14CK0RAyy2zY4gRs2MpnU5r"
"/feWf60OkLtnPzN34+Xnlg5xf7Jl00wkHRCeJG17L3SklOidAPxWnE+Wm4BS"
"SOzdQBgiZOjlhrYS1+TIU3NP5H7BrtKFcf+ZwBULibf29L7LkDOgQbie1+43"
"lU+8SHAyBwAeGYMfZ"
"4",
"F///////////////////////////////////////////////////////////"
"////////////////////////////////////////////////////////////"
"////////////////////////////////////////////////////////////"
"////////////////////////////////////////////////////////////"
"////////////m5uqd"
},
#endif
#ifdef DH1792
{
224,
"DH-1792",
"2",
"IPo3wjvfS7vBYnFHwJHmesA51od9fnR8Aenezif4qLE2HX+YCv1tpvHA8yLH"
"yYbKe9QfSHHtOgVjK8AYEyPirpXxlmdykGuj+dX7EiWMRGYc+v1kKkqmCn0o"
"5tU416O/1HXTpQ2Hps0buchUD+HlCMrSgnIqRxK6Fjr0ZfiCS4XgAD6sLgi0"
"BxKFMxDsVzpGMNwF5Lj2R/cJiTi0cNDDY3gn4lK/PRUsJtRKU+9sxy0q5Yof"
"aG5VO8VcHkZJVwUKhDFHkZYWMHV808TGHXM2RQ9kRa2QvS2mXxMrDSCloQ/"
"4",
"F///////////////////////////////////////////////////////////"
"////////////////////////////////////////////////////////////"
"////////////////////////////////////////////////////////////"
"////////////////////////////////////////////////////////////"
"//////////////////////////////////////////////////////mT/sd"
},
#endif
#ifdef DH2048
{
256,
"DH-2048",
"2",
"5sR1VmdsQQzzjN0iridVVyveug6sAC3+/jTIHSgEoimPOREXQ05r2WJZJAF2"
"CRu8kuusiPw2ivRli+fdLr63v1uZG5nQa28uLwNxZEsu4gu6TrGjepXeXm4Z"
"CVOC1HMmi660fLZ2ruHLa4v2NWex2Zx91/y4ygPlZM+K//iy+Gft9Ma9Ayn0"
"eYwofZeUL9vJSfutPVp2ZrIEUQDBKMvMm0SRSLiUjDtzXqrH+b/wuwIFG1K4"
"var3ucsT45mDzD9qb3tBdksSPZbr6yrELV8h+qmjiBr15oHKEglS0XwSvCap"
"abUn5XPPVoaKv13+tOnG9mGgzQ8JeClVXN63Q+GGEF"
"4",
"3///////////////////////////////////////////////////////////"
"////////////////////////////////////////////////////////////"
"////////////////////////////////////////////////////////////"
"////////////////////////////////////////////////////////////"
"////////////////////////////////////////////////////////////"
"/////////////////////////////////////////m8MPh"
},
#endif
#ifdef DH2560
{
320,
"DH-2560",
"3",
"G7UVKk+N6LfpGkdBP6XLB4QJ3wzee5YH/3o6tBDMwr4FS8YjCmeP6l4gu0hX"
"dzY2Rive4TYOu4Akm4naZuv32d71/2lQeNcO23BNYOEPxtn9BU8uYfaHP9Mo"
"M+m76oUCiI5uqpag5RH3BO34FyE4BiKkzjEXq9xxc8ERacG8Mo8DNiXu79p9"
"Q/0wsRz+W/lIN4gYw3w4iLMooAGnDrhcj5cZb0HysHWYfqmFo+jTBP6Egi0g"
"cmVO2qWQh2cZIQMfppaf1Ffq0XGIJpgDFyOHPl3NVxDabVK1tkVct+hathxJ"
"UTdqZmR2VFwMASXjfgj4VFdvFCUxV8Xr8JcwXkwlMjOJbAl0LoCa4M7hpYvz"
"G/0XviGCpv7qQaONKtsiQ6mHhMcyo9hBCRZXtNPkfPMZkPeV05akvaDs6Ek7"
"DZ62oKR"
"4",
"3///////////////////////////////////////////////////////////"
"////////////////////////////////////////////////////////////"
"////////////////////////////////////////////////////////////"
"////////////////////////////////////////////////////////////"
"////////////////////////////////////////////////////////////"
"////////////////////////////////////////////////////////////"
"////////////////////////////////////////////////////////////"
"/////mKFpF"
},
#endif
#ifdef DH3072
{
384,
"DH-3072",
"2",
"1zsV6XgY57R/hu2RR4H/BjwRqmQL9h+Dc5rgoWOcqiTS8qpVTWafi1KFV77V"
"rUcjcer1EDgCV0tpzlemtyrC2pHpw7hr3EEl2evfWOvg05FRI6mKc2UPNv2c"
"2Bjww4LD/tdsLleX7AHHXCXFSSyd6C3qWq7BqABZriSpQeaEtXbWfeC6ytFe"
"2i3VeQsLa40XQ21UxwhPAjamjSOfYzkW7xi0fwI1e+4OQiFcWOfOuvswoaEf"
"MIICyAmVp67vjGo66dk81dMemyplipgXAWPdl7ppnDd6cEjyN4N90D7kQiNg"
"lVmJlKLecldOUtdIqMnbJCbiN/t/3/AEFaokGO9om5ckc6M9gG5PG0T7Oh1N"
"dSx/PstGdxwvs9DOwjyo5wl5C9QSLtUYJl2+GZYMj6WfsgCrb6jjRJJJQe2C"
"y7wUcBILbRsP3lYT8s14zm4xFBrfMUoLN287j3wQ1TNUXjYSCi4ZLKT1XDai"
"93345OiutLOqGGikFg6ypnymJK3yeHuul"
"4",
"3///////////////////////////////////////////////////////////"
"////////////////////////////////////////////////////////////"
"////////////////////////////////////////////////////////////"
"////////////////////////////////////////////////////////////"
"////////////////////////////////////////////////////////////"
"////////////////////////////////////////////////////////////"
"////////////////////////////////////////////////////////////"
"////////////////////////////////////////////////////////////"
"/////////////////////////////m32nN"
},
#endif
#ifdef DH4096
{
512,
"DH-4096",
"3",
"Id8ukxZdao3hS0NGTKAXdt3c8PpiyigIyBY8lwOHjM2cqkaZgwvr1pA6OowS"
"32kJkeOqKB8gNTZZZVqOFkPXgvC4WveUgA5a7rhTj28pDidNROmMO70CCcSw"
"aHI3GLFuEMz3JJyvQKGaGwpV3C9gS70dFWTxEfNRzdYEdvIic8/SXI79VgNP"
"LGR68nzd4qxCgaLpVBnWsanRp7mfEj52S/7Kxjs14lrbAOMjCuHgN4F6THWh"
"PNhG0VXfFFIwAMW2unrfpdo+gQHNclqCf2N1FALpABzvUesgs3wIP+QTMqms"
"os/AkuulG7MusbeFl3SoCtaoW12CF038ZbqW+e+DKI1zObhtsLanvaiZm/N4"
"BsJirW7avcWNQYm1oYjZ2bR/jYqfoJ0CLXLO/vqHb8J9a5VE9nz7cqMD3/MH"
"k/g7BapsOtKuol6ipbUvxQPtf4KCwqQQ40JeqgS6amivI/aLu05S7bAxKOwE"
"Yu8YxjN6lXm3co5Wy+BmNSuRlzKhxICyHEqMfKwUtm48XHzHuPaGQzHgkn6H"
"3A+FQjQGLHewADYlbfdTF3sHYyc5k9h/9cYVkbmv7bQze53CJGr3T1hZYbN6"
"+fuz0SPnfjiKu+bWD+8RYtZpLs2+f32huMz3OqoryGfULxC2aEjL2rdBn+ZR"
"PT0+ZAUyLSAVHbsul++cawh"
"4",
"////////////////////////////////////////////////////////////"
"////////////////////////////////////////////////////////////"
"////////////////////////////////////////////////////////////"
"////////////////////////////////////////////////////////////"
"////////////////////////////////////////////////////////////"
"////////////////////////////////////////////////////////////"
"////////////////////////////////////////////////////////////"
"////////////////////////////////////////////////////////////"
"////////////////////////////////////////////////////////////"
"////////////////////////////////////////////////////////////"
"////////////////////////////////////////////////////////////"
"/////////////////////m8pOF"
},
#endif
{

2
ecc.c
View File

@ -590,7 +590,7 @@ int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key)
int x, res, err;
ecc_point *base;
mp_int prime;
unsigned char buf[4096];
unsigned char buf[128];
_ARGCHK(key != NULL);

4
hash.c
View File

@ -27,7 +27,7 @@ int hash_memory(int hash, const unsigned char *data, unsigned long len, unsigned
int hash_filehandle(int hash, FILE *in, unsigned char *dst, unsigned long *outlen)
{
#ifdef NO_FILE
return CRYPT_ERROR;
return CRYPT_NOP;
#else
hash_state md;
unsigned char buf[512];
@ -64,7 +64,7 @@ int hash_filehandle(int hash, FILE *in, unsigned char *dst, unsigned long *outle
int hash_file(int hash, const char *fname, unsigned char *dst, unsigned long *outlen)
{
#ifdef NO_FILE
return CRYPT_ERROR;
return CRYPT_NOP;
#else
FILE *in;
int err;

29
hmac.c
View File

@ -37,7 +37,8 @@ int hmac_init(hmac_state *hmac, int hash, const unsigned char *key, unsigned lon
return err;
}
if (keylen == 0) {
/* valid key length? */
if (keylen == 0 || keylen > MAXBLOCKSIZE) {
return CRYPT_INVALID_KEYSIZE;
}
@ -88,7 +89,7 @@ int hmac_process(hmac_state *hmac, const unsigned char *buf, unsigned long len)
return CRYPT_OK;
}
int hmac_done(hmac_state *hmac, unsigned char *hashOut)
int hmac_done(hmac_state *hmac, unsigned char *hashOut, unsigned long *outlen)
{
unsigned char buf[MAXBLOCKSIZE];
unsigned char isha[MAXBLOCKSIZE];
@ -103,11 +104,17 @@ int hmac_done(hmac_state *hmac, unsigned char *hashOut)
return err;
}
/* ensure the output size is valid */
hashsize = hash_descriptor[hash].hashsize;
if (*outlen < hashsize) {
return CRYPT_BUFFER_OVERFLOW;
}
*outlen = hashsize;
// Get the hash of the first HMAC vector plus the data
hash_descriptor[hash].done(&hmac->md, isha);
// Create the second HMAC vector vector for step (3)
hashsize = hash_descriptor[hash].hashsize;
for(i=0; i < HMAC_BLOCKSIZE; i++) {
buf[i] = hmac->key[i] ^ 0x5C;
}
@ -138,20 +145,16 @@ int hmac_memory(int hash, const unsigned char *key, unsigned long keylen,
if((err = hash_is_valid(hash)) != CRYPT_OK) {
return err;
}
if (hash_descriptor[hash].hashsize > *dstlen) {
return CRYPT_BUFFER_OVERFLOW;
}
*dstlen = hash_descriptor[hash].hashsize;
if ((err = hmac_init(&hmac, hash, key, keylen)) != CRYPT_OK) {
return err;
}
if ((err = hmac_process(&hmac, data, len)) != CRYPT_OK) {
return err;
}
if ((err = hmac_done(&hmac, dst)) != CRYPT_OK) {
if ((err = hmac_done(&hmac, dst, dstlen)) != CRYPT_OK) {
return err;
}
return CRYPT_OK;
@ -163,7 +166,7 @@ int hmac_file(int hash, const char *fname, const unsigned char *key,
unsigned char *dst, unsigned long *dstlen)
{
#ifdef NO_FILE
return CRYPT_ERROR;
return CRYPT_NOP;
#else
hmac_state hmac;
FILE *in;
@ -178,10 +181,6 @@ int hmac_file(int hash, const char *fname, const unsigned char *key,
if((err = hash_is_valid(hash)) != CRYPT_OK) {
return err;
}
if (hash_descriptor[hash].hashsize > *dstlen) {
return CRYPT_BUFFER_OVERFLOW;
}
*dstlen = hash_descriptor[hash].hashsize;
if ((err = hmac_init(&hmac, hash, key, keylen)) != CRYPT_OK) {
return err;
@ -203,7 +202,7 @@ int hmac_file(int hash, const char *fname, const unsigned char *key,
(void)fclose(in);
/* get final hmac */
if ((err = hmac_done(&hmac, dst)) != CRYPT_OK) {
if ((err = hmac_done(&hmac, dst, dstlen)) != CRYPT_OK) {
return err;
}

View File

@ -1,53 +0,0 @@
Legal Issues Regarding LibTomCrypt
Tom St Denis
The bulk of the code was written or donated under the TDCAL "Tom Doesn't Care About License" license. It entitles the developer to free-reign on
the use and distribution of derived works, commercial or otherwise. Certain files are taken from public domain packages.
DES.C
-----
Author: Unknown, Submitted by Dobes Vandermeer
Email : dobes@smartt.com
Disclaimer: None
Status: TDCAL submission by Dobes, modified [not original]
MD4.C
-----
Author: Dobes Vandermeer
Email : dobes@smartt.com
Disclaimer: None
Status: TDCAL submission by Dobes, modified [not original]
HMAC.C
------
Author: Dobes Vandermeer
Email: dobes@smartt.com
Disclaimer: None
Status: TDCAL submission by Dobes, modified [not original]
MPI.C
-----
Author: Original [v0.80 and prior] Michael Fromberger, Current [v0.81 and later] Tom St Denis
Email: tomstdenis@iahu.ca
Disclaimer: None
Status: TDCAL submission by Tom
RC2.C
-----
Author: Unknown, found on public domain archive [www.wiretapped.net]
Email: none
Disclaimer: Possible legal issues [should remove RC2/RC5/RC6 to simplify legal issues]
Status: Public Domain, questionable legal status, modified [not original]
SAFER.C
-------
Author: [copied verbatim]
----
* AUTHOR: Richard De Moliner (demoliner@isi.ee.ethz.ch)
* Signal and Information Processing Laboratory
* Swiss Federal Institute of Technology
* CH-8092 Zuerich, Switzerland
----
Email: demoliner@isi.ee.ethz.ch
Disclaimer: Appears to be Public Domain [not quite sure]
Status: Public Domain, modified [not original]

View File

@ -9,7 +9,7 @@
# a build. This is easy to remedy though, for those that have problems.
# The version
VERSION=0.89
VERSION=0.90
#ch1-01-1
# Compiler and Linker Names
@ -49,7 +49,6 @@ SMALL=small
PROF=x86_prof
TV=tv_gen
#LIBPATH-The directory for libtomcrypt to be installed to.
#INCPATH-The directory to install the header files for libtomcrypt.
#DATAPATH-The directory to install the pdf docs.
@ -67,7 +66,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 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 \
prime.o twofish.o packet.o hmac.o strings.o $(MPIOBJECT)
prime.o twofish.o packet.o hmac.o strings.o rmd128.o rmd160.o $(MPIOBJECT)
TESTOBJECTS=demos/test.o
HASHOBJECTS=demos/hashsum.o
@ -98,9 +97,10 @@ aes.o: aes.c aes_tab.c
sha512.o: sha512.c sha384.c
#This rule makes the libtomcrypt library.
library: $(OBJECTS)
$(AR) $(ARFLAGS) $(LIBNAME) $(OBJECTS)
ranlib $(LIBNAME)
library: $(LIBNAME)
$(LIBNAME): $(OBJECTS)
$(AR) $(ARFLAGS) $@ $(OBJECTS)
#This rule makes the test program included with libtomcrypt
test: library $(TESTOBJECTS)

View File

@ -10,7 +10,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 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 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 rmd128.obj rmd160.obj
library: $(OBJECTS)
lib /out:tomcrypt.lib $(OBJECTS)

1062
mpi.c

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -6,7 +6,7 @@
#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 XMALLOC malloc
@ -15,8 +15,8 @@
#define XFREE free
#define XCLOCK clock
#define XCLOCKS_PER_SEC CLOCKS_PER_SEC
#define LTC_TEST
#define SMALL_CODE
#define LTC_TEST
#define BLOWFISH
#define RC2
#define RC5
@ -24,9 +24,9 @@
#define SAFERP
#define SAFER
#define RIJNDAEL
#define SERPENT
#define XTEA
#define TWOFISH
#define TWOFISH_TABLES
#define DES
#define CAST5
#define NOEKEON
@ -43,6 +43,8 @@
#define MD5
#define MD4
#define MD2
#define RIPEMD128
#define RIPEMD160
#define HMAC
#define BASE64
#define YARROW
@ -52,7 +54,6 @@
#define MRSA
#define MDH
#define MECC
#define KR
#define DH768
#define DH1024
#define DH1280

View File

@ -54,6 +54,22 @@ struct md2_state {
};
#endif
#ifdef RIPEMD128
struct rmd128_state {
ulong64 length;
unsigned char buf[64];
unsigned long curlen, state[4];
};
#endif
#ifdef RIPEMD160
struct rmd160_state {
ulong64 length;
unsigned char buf[64];
unsigned long curlen, state[5];
};
#endif
typedef union Hash_state {
#ifdef SHA512
struct sha512_state sha512;
@ -76,6 +92,12 @@ typedef union Hash_state {
#ifdef TIGER
struct tiger_state tiger;
#endif
#ifdef RIPEMD128
struct rmd128_state rmd128;
#endif
#ifdef RIPEMD160
struct rmd160_state rmd160;
#endif
} hash_state;
extern struct _hash_descriptor {
@ -153,6 +175,23 @@ extern int tiger_test(void);
extern const struct _hash_descriptor tiger_desc;
#endif
#ifdef RIPEMD128
extern void rmd128_init(hash_state * md);
extern void rmd128_process(hash_state * md, const unsigned char *buf, unsigned long len);
extern void rmd128_done(hash_state * md, unsigned char *hash);
extern int rmd128_test(void);
extern const struct _hash_descriptor rmd128_desc;
#endif
#ifdef RIPEMD160
extern void rmd160_init(hash_state * md);
extern void rmd160_process(hash_state * md, const unsigned char *buf, unsigned long len);
extern void rmd160_done(hash_state * md, unsigned char *hash);
extern int rmd160_test(void);
extern const struct _hash_descriptor rmd160_desc;
#endif
extern int find_hash(const char *name);
extern int find_hash_id(unsigned char ID);
extern int register_hash(const struct _hash_descriptor *hash);
@ -174,7 +213,7 @@ typedef struct Hmac_state {
extern int hmac_init(hmac_state *hmac, int hash, const unsigned char *key, unsigned long keylen);
extern int hmac_process(hmac_state *hmac, const unsigned char *buf, unsigned long len);
extern int hmac_done(hmac_state *hmac, unsigned char *hash);
extern int hmac_done(hmac_state *hmac, unsigned char *hashOut, unsigned long *outlen);
extern int hmac_test(void);
extern int hmac_memory(int hash, const unsigned char *key, unsigned long keylen,
const unsigned char *data, unsigned long len,

View File

@ -194,6 +194,24 @@ typedef unsigned long ulong32;
#define ROR(x,n) _lrotr(x,n)
#define ROL(x,n) _lrotl(x,n)
#elif defined(__GNUC__) && defined(__i386__)
static inline unsigned long ROL(unsigned long word, int i)
{
__asm__("roll %%cl,%0"
:"=r" (word)
:"0" (word),"c" (i));
return word;
}
static inline unsigned long ROR(unsigned long word, int i)
{
__asm__("rorl %%cl,%0"
:"=r" (word)
:"0" (word),"c" (i));
return word;
}
#else
/* rotates the hard way */

366
rmd128.c Normal file
View File

@ -0,0 +1,366 @@
/* Implementation of RIPEMD-128 based on the source by Antoon Bosselaers, ESAT-COSIC
*
* This source has been radically overhauled to be portable and work within
* the LibTomCrypt API by Tom St Denis
*/
#include "mycrypt.h"
#ifdef RIPEMD128
const struct _hash_descriptor rmd128_desc =
{
"rmd128",
8,
16,
64,
&rmd128_init,
&rmd128_process,
&rmd128_done,
&rmd128_test
};
/* the four basic functions F(), G() and H() */
#define F(x, y, z) ((x) ^ (y) ^ (z))
#define G(x, y, z) (((x) & (y)) | (~(x) & (z)))
#define H(x, y, z) (((x) | ~(y)) ^ (z))
#define I(x, y, z) (((x) & (z)) | ((y) & ~(z)))
/* the eight basic operations FF() through III() */
#define FF(a, b, c, d, x, s) \
(a) += F((b), (c), (d)) + (x);\
(a) = ROL((a), (s));
#define GG(a, b, c, d, x, s) \
(a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\
(a) = ROL((a), (s));
#define HH(a, b, c, d, x, s) \
(a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\
(a) = ROL((a), (s));
#define II(a, b, c, d, x, s) \
(a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\
(a) = ROL((a), (s));
#define FFF(a, b, c, d, x, s) \
(a) += F((b), (c), (d)) + (x);\
(a) = ROL((a), (s));
#define GGG(a, b, c, d, x, s) \
(a) += G((b), (c), (d)) + (x) + 0x6d703ef3UL;\
(a) = ROL((a), (s));
#define HHH(a, b, c, d, x, s) \
(a) += H((b), (c), (d)) + (x) + 0x5c4dd124UL;\
(a) = ROL((a), (s));
#define III(a, b, c, d, x, s) \
(a) += I((b), (c), (d)) + (x) + 0x50a28be6UL;\
(a) = ROL((a), (s));
#ifdef CLEAN_STACK
static void _rmd128_compress(hash_state *md)
#else
static void rmd128_compress(hash_state *md)
#endif
{
unsigned long aa,bb,cc,dd,aaa,bbb,ccc,ddd,X[16];
int i;
/* load words X */
for (i = 0; i < 16; i++){
LOAD32L(X[i], md->rmd128.buf + (4 * i));
}
/* load state */
aa = aaa = md->rmd128.state[0];
bb = bbb = md->rmd128.state[1];
cc = ccc = md->rmd128.state[2];
dd = ddd = md->rmd128.state[3];
/* round 1 */
FF(aa, bb, cc, dd, X[ 0], 11);
FF(dd, aa, bb, cc, X[ 1], 14);
FF(cc, dd, aa, bb, X[ 2], 15);
FF(bb, cc, dd, aa, X[ 3], 12);
FF(aa, bb, cc, dd, X[ 4], 5);
FF(dd, aa, bb, cc, X[ 5], 8);
FF(cc, dd, aa, bb, X[ 6], 7);
FF(bb, cc, dd, aa, X[ 7], 9);
FF(aa, bb, cc, dd, X[ 8], 11);
FF(dd, aa, bb, cc, X[ 9], 13);
FF(cc, dd, aa, bb, X[10], 14);
FF(bb, cc, dd, aa, X[11], 15);
FF(aa, bb, cc, dd, X[12], 6);
FF(dd, aa, bb, cc, X[13], 7);
FF(cc, dd, aa, bb, X[14], 9);
FF(bb, cc, dd, aa, X[15], 8);
/* round 2 */
GG(aa, bb, cc, dd, X[ 7], 7);
GG(dd, aa, bb, cc, X[ 4], 6);
GG(cc, dd, aa, bb, X[13], 8);
GG(bb, cc, dd, aa, X[ 1], 13);
GG(aa, bb, cc, dd, X[10], 11);
GG(dd, aa, bb, cc, X[ 6], 9);
GG(cc, dd, aa, bb, X[15], 7);
GG(bb, cc, dd, aa, X[ 3], 15);
GG(aa, bb, cc, dd, X[12], 7);
GG(dd, aa, bb, cc, X[ 0], 12);
GG(cc, dd, aa, bb, X[ 9], 15);
GG(bb, cc, dd, aa, X[ 5], 9);
GG(aa, bb, cc, dd, X[ 2], 11);
GG(dd, aa, bb, cc, X[14], 7);
GG(cc, dd, aa, bb, X[11], 13);
GG(bb, cc, dd, aa, X[ 8], 12);
/* round 3 */
HH(aa, bb, cc, dd, X[ 3], 11);
HH(dd, aa, bb, cc, X[10], 13);
HH(cc, dd, aa, bb, X[14], 6);
HH(bb, cc, dd, aa, X[ 4], 7);
HH(aa, bb, cc, dd, X[ 9], 14);
HH(dd, aa, bb, cc, X[15], 9);
HH(cc, dd, aa, bb, X[ 8], 13);
HH(bb, cc, dd, aa, X[ 1], 15);
HH(aa, bb, cc, dd, X[ 2], 14);
HH(dd, aa, bb, cc, X[ 7], 8);
HH(cc, dd, aa, bb, X[ 0], 13);
HH(bb, cc, dd, aa, X[ 6], 6);
HH(aa, bb, cc, dd, X[13], 5);
HH(dd, aa, bb, cc, X[11], 12);
HH(cc, dd, aa, bb, X[ 5], 7);
HH(bb, cc, dd, aa, X[12], 5);
/* round 4 */
II(aa, bb, cc, dd, X[ 1], 11);
II(dd, aa, bb, cc, X[ 9], 12);
II(cc, dd, aa, bb, X[11], 14);
II(bb, cc, dd, aa, X[10], 15);
II(aa, bb, cc, dd, X[ 0], 14);
II(dd, aa, bb, cc, X[ 8], 15);
II(cc, dd, aa, bb, X[12], 9);
II(bb, cc, dd, aa, X[ 4], 8);
II(aa, bb, cc, dd, X[13], 9);
II(dd, aa, bb, cc, X[ 3], 14);
II(cc, dd, aa, bb, X[ 7], 5);
II(bb, cc, dd, aa, X[15], 6);
II(aa, bb, cc, dd, X[14], 8);
II(dd, aa, bb, cc, X[ 5], 6);
II(cc, dd, aa, bb, X[ 6], 5);
II(bb, cc, dd, aa, X[ 2], 12);
/* parallel round 1 */
III(aaa, bbb, ccc, ddd, X[ 5], 8);
III(ddd, aaa, bbb, ccc, X[14], 9);
III(ccc, ddd, aaa, bbb, X[ 7], 9);
III(bbb, ccc, ddd, aaa, X[ 0], 11);
III(aaa, bbb, ccc, ddd, X[ 9], 13);
III(ddd, aaa, bbb, ccc, X[ 2], 15);
III(ccc, ddd, aaa, bbb, X[11], 15);
III(bbb, ccc, ddd, aaa, X[ 4], 5);
III(aaa, bbb, ccc, ddd, X[13], 7);
III(ddd, aaa, bbb, ccc, X[ 6], 7);
III(ccc, ddd, aaa, bbb, X[15], 8);
III(bbb, ccc, ddd, aaa, X[ 8], 11);
III(aaa, bbb, ccc, ddd, X[ 1], 14);
III(ddd, aaa, bbb, ccc, X[10], 14);
III(ccc, ddd, aaa, bbb, X[ 3], 12);
III(bbb, ccc, ddd, aaa, X[12], 6);
/* parallel round 2 */
HHH(aaa, bbb, ccc, ddd, X[ 6], 9);
HHH(ddd, aaa, bbb, ccc, X[11], 13);
HHH(ccc, ddd, aaa, bbb, X[ 3], 15);
HHH(bbb, ccc, ddd, aaa, X[ 7], 7);
HHH(aaa, bbb, ccc, ddd, X[ 0], 12);
HHH(ddd, aaa, bbb, ccc, X[13], 8);
HHH(ccc, ddd, aaa, bbb, X[ 5], 9);
HHH(bbb, ccc, ddd, aaa, X[10], 11);
HHH(aaa, bbb, ccc, ddd, X[14], 7);
HHH(ddd, aaa, bbb, ccc, X[15], 7);
HHH(ccc, ddd, aaa, bbb, X[ 8], 12);
HHH(bbb, ccc, ddd, aaa, X[12], 7);
HHH(aaa, bbb, ccc, ddd, X[ 4], 6);
HHH(ddd, aaa, bbb, ccc, X[ 9], 15);
HHH(ccc, ddd, aaa, bbb, X[ 1], 13);
HHH(bbb, ccc, ddd, aaa, X[ 2], 11);
/* parallel round 3 */
GGG(aaa, bbb, ccc, ddd, X[15], 9);
GGG(ddd, aaa, bbb, ccc, X[ 5], 7);
GGG(ccc, ddd, aaa, bbb, X[ 1], 15);
GGG(bbb, ccc, ddd, aaa, X[ 3], 11);
GGG(aaa, bbb, ccc, ddd, X[ 7], 8);
GGG(ddd, aaa, bbb, ccc, X[14], 6);
GGG(ccc, ddd, aaa, bbb, X[ 6], 6);
GGG(bbb, ccc, ddd, aaa, X[ 9], 14);
GGG(aaa, bbb, ccc, ddd, X[11], 12);
GGG(ddd, aaa, bbb, ccc, X[ 8], 13);
GGG(ccc, ddd, aaa, bbb, X[12], 5);
GGG(bbb, ccc, ddd, aaa, X[ 2], 14);
GGG(aaa, bbb, ccc, ddd, X[10], 13);
GGG(ddd, aaa, bbb, ccc, X[ 0], 13);
GGG(ccc, ddd, aaa, bbb, X[ 4], 7);
GGG(bbb, ccc, ddd, aaa, X[13], 5);
/* parallel round 4 */
FFF(aaa, bbb, ccc, ddd, X[ 8], 15);
FFF(ddd, aaa, bbb, ccc, X[ 6], 5);
FFF(ccc, ddd, aaa, bbb, X[ 4], 8);
FFF(bbb, ccc, ddd, aaa, X[ 1], 11);
FFF(aaa, bbb, ccc, ddd, X[ 3], 14);
FFF(ddd, aaa, bbb, ccc, X[11], 14);
FFF(ccc, ddd, aaa, bbb, X[15], 6);
FFF(bbb, ccc, ddd, aaa, X[ 0], 14);
FFF(aaa, bbb, ccc, ddd, X[ 5], 6);
FFF(ddd, aaa, bbb, ccc, X[12], 9);
FFF(ccc, ddd, aaa, bbb, X[ 2], 12);
FFF(bbb, ccc, ddd, aaa, X[13], 9);
FFF(aaa, bbb, ccc, ddd, X[ 9], 12);
FFF(ddd, aaa, bbb, ccc, X[ 7], 5);
FFF(ccc, ddd, aaa, bbb, X[10], 15);
FFF(bbb, ccc, ddd, aaa, X[14], 8);
/* combine results */
ddd += cc + md->rmd128.state[1]; /* final result for MDbuf[0] */
md->rmd128.state[1] = md->rmd128.state[2] + dd + aaa;
md->rmd128.state[2] = md->rmd128.state[3] + aa + bbb;
md->rmd128.state[3] = md->rmd128.state[0] + bb + ccc;
md->rmd128.state[0] = ddd;
}
#ifdef CLEAN_STACK
static void rmd128_compress(hash_state *md)
{
_rmd128_compress(md);
burn_stack(sizeof(unsigned long) * 24 + sizeof(int));
}
#endif
void rmd128_init(hash_state * md)
{
_ARGCHK(md != NULL);
md->rmd128.state[0] = 0x67452301UL;
md->rmd128.state[1] = 0xefcdab89UL;
md->rmd128.state[2] = 0x98badcfeUL;
md->rmd128.state[3] = 0x10325476UL;
md->rmd128.curlen = 0;
md->rmd128.length = 0;
}
void rmd128_process(hash_state * md, const unsigned char *buf, unsigned long len)
{
unsigned long n;
_ARGCHK(md != NULL);
_ARGCHK(buf != NULL);
while (len > 0) {
n = MIN(len, (64 - md->rmd128.curlen));
memcpy(md->rmd128.buf + md->rmd128.curlen, buf, (size_t)n);
md->rmd128.curlen += n;
buf += n;
len -= n;
/* is 64 bytes full? */
if (md->rmd128.curlen == 64) {
rmd128_compress(md);
md->rmd128.length += 512;
md->rmd128.curlen = 0;
}
}
}
void rmd128_done(hash_state * md, unsigned char *hash)
{
int i;
_ARGCHK(md != NULL);
_ARGCHK(hash != NULL);
/* increase the length of the message */
md->rmd128.length += md->rmd128.curlen * 8;
/* append the '1' bit */
md->rmd128.buf[md->rmd128.curlen++] = (unsigned char)0x80;
/* if the length is currently above 56 bytes we append zeros
* then compress. Then we can fall back to padding zeros and length
* encoding like normal.
*/
if (md->rmd128.curlen > 56) {
while (md->rmd128.curlen < 64) {
md->rmd128.buf[md->rmd128.curlen++] = (unsigned char)0;
}
rmd128_compress(md);
md->rmd128.curlen = 0;
}
/* pad upto 56 bytes of zeroes */
while (md->rmd128.curlen < 56) {
md->rmd128.buf[md->rmd128.curlen++] = (unsigned char)0;
}
/* store length */
STORE64L(md->rmd128.length, md->rmd128.buf+56);
rmd128_compress(md);
/* copy output */
for (i = 0; i < 4; i++) {
STORE32L(md->rmd128.state[i], hash+(4*i));
}
#ifdef CLEAN_STACK
zeromem(md, sizeof(hash_state));
#endif
}
int rmd128_test(void)
{
static const struct {
char *msg;
unsigned char md[16];
} tests[] = {
{ "",
{ 0xcd, 0xf2, 0x62, 0x13, 0xa1, 0x50, 0xdc, 0x3e,
0xcb, 0x61, 0x0f, 0x18, 0xf6, 0xb3, 0x8b, 0x46 }
},
{ "a",
{ 0x86, 0xbe, 0x7a, 0xfa, 0x33, 0x9d, 0x0f, 0xc7,
0xcf, 0xc7, 0x85, 0xe7, 0x2f, 0x57, 0x8d, 0x33 }
},
{ "abc",
{ 0xc1, 0x4a, 0x12, 0x19, 0x9c, 0x66, 0xe4, 0xba,
0x84, 0x63, 0x6b, 0x0f, 0x69, 0x14, 0x4c, 0x77 }
},
{ "message digest",
{ 0x9e, 0x32, 0x7b, 0x3d, 0x6e, 0x52, 0x30, 0x62,
0xaf, 0xc1, 0x13, 0x2d, 0x7d, 0xf9, 0xd1, 0xb8 }
},
{ "abcdefghijklmnopqrstuvwxyz",
{ 0xfd, 0x2a, 0xa6, 0x07, 0xf7, 0x1d, 0xc8, 0xf5,
0x10, 0x71, 0x49, 0x22, 0xb3, 0x71, 0x83, 0x4e }
},
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
{ 0xd1, 0xe9, 0x59, 0xeb, 0x17, 0x9c, 0x91, 0x1f,
0xae, 0xa4, 0x62, 0x4c, 0x60, 0xc5, 0xc7, 0x02 }
}
};
int x;
unsigned char buf[16];
hash_state md;
for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
rmd128_init(&md);
rmd128_process(&md, (unsigned char *)tests[x].msg, strlen(tests[x].msg));
rmd128_done(&md, buf);
if (memcmp(buf, tests[x].md, 16) != 0) {
#if 0
printf("Failed test %d\n", x);
#endif
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
}
#endif

425
rmd160.c Normal file
View File

@ -0,0 +1,425 @@
/* Implementation of RIPEMD-160 based on the source by Antoon Bosselaers, ESAT-COSIC
*
* This source has been radically overhauled to be portable and work within
* the LibTomCrypt API by Tom St Denis
*/
#include "mycrypt.h"
#ifdef RIPEMD160
const struct _hash_descriptor rmd160_desc =
{
"rmd160",
9,
20,
64,
&rmd160_init,
&rmd160_process,
&rmd160_done,
&rmd160_test
};
/* the five basic functions F(), G() and H() */
#define F(x, y, z) ((x) ^ (y) ^ (z))
#define G(x, y, z) (((x) & (y)) | (~(x) & (z)))
#define H(x, y, z) (((x) | ~(y)) ^ (z))
#define I(x, y, z) (((x) & (z)) | ((y) & ~(z)))
#define J(x, y, z) ((x) ^ ((y) | ~(z)))
/* the ten basic operations FF() through III() */
#define FF(a, b, c, d, e, x, s) \
(a) += F((b), (c), (d)) + (x);\
(a) = ROL((a), (s)) + (e);\
(c) = ROL((c), 10);
#define GG(a, b, c, d, e, x, s) \
(a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\
(a) = ROL((a), (s)) + (e);\
(c) = ROL((c), 10);
#define HH(a, b, c, d, e, x, s) \
(a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\
(a) = ROL((a), (s)) + (e);\
(c) = ROL((c), 10);
#define II(a, b, c, d, e, x, s) \
(a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\
(a) = ROL((a), (s)) + (e);\
(c) = ROL((c), 10);
#define JJ(a, b, c, d, e, x, s) \
(a) += J((b), (c), (d)) + (x) + 0xa953fd4eUL;\
(a) = ROL((a), (s)) + (e);\
(c) = ROL((c), 10);
#define FFF(a, b, c, d, e, x, s) \
(a) += F((b), (c), (d)) + (x);\
(a) = ROL((a), (s)) + (e);\
(c) = ROL((c), 10);
#define GGG(a, b, c, d, e, x, s) \
(a) += G((b), (c), (d)) + (x) + 0x7a6d76e9UL;\
(a) = ROL((a), (s)) + (e);\
(c) = ROL((c), 10);
#define HHH(a, b, c, d, e, x, s) \
(a) += H((b), (c), (d)) + (x) + 0x6d703ef3UL;\
(a) = ROL((a), (s)) + (e);\
(c) = ROL((c), 10);
#define III(a, b, c, d, e, x, s) \
(a) += I((b), (c), (d)) + (x) + 0x5c4dd124UL;\
(a) = ROL((a), (s)) + (e);\
(c) = ROL((c), 10);
#define JJJ(a, b, c, d, e, x, s) \
(a) += J((b), (c), (d)) + (x) + 0x50a28be6UL;\
(a) = ROL((a), (s)) + (e);\
(c) = ROL((c), 10);
#ifdef CLEAN_STACK
static void _rmd160_compress(hash_state *md)
#else
static void rmd160_compress(hash_state *md)
#endif
{
unsigned long aa,bb,cc,dd,ee,aaa,bbb,ccc,ddd,eee,X[16];
int i;
/* load words X */
for (i = 0; i < 16; i++){
LOAD32L(X[i], md->rmd160.buf + (4 * i));
}
/* load state */
aa = aaa = md->rmd160.state[0];
bb = bbb = md->rmd160.state[1];
cc = ccc = md->rmd160.state[2];
dd = ddd = md->rmd160.state[3];
ee = eee = md->rmd160.state[4];
/* round 1 */
FF(aa, bb, cc, dd, ee, X[ 0], 11);
FF(ee, aa, bb, cc, dd, X[ 1], 14);
FF(dd, ee, aa, bb, cc, X[ 2], 15);
FF(cc, dd, ee, aa, bb, X[ 3], 12);
FF(bb, cc, dd, ee, aa, X[ 4], 5);
FF(aa, bb, cc, dd, ee, X[ 5], 8);
FF(ee, aa, bb, cc, dd, X[ 6], 7);
FF(dd, ee, aa, bb, cc, X[ 7], 9);
FF(cc, dd, ee, aa, bb, X[ 8], 11);
FF(bb, cc, dd, ee, aa, X[ 9], 13);
FF(aa, bb, cc, dd, ee, X[10], 14);
FF(ee, aa, bb, cc, dd, X[11], 15);
FF(dd, ee, aa, bb, cc, X[12], 6);
FF(cc, dd, ee, aa, bb, X[13], 7);
FF(bb, cc, dd, ee, aa, X[14], 9);
FF(aa, bb, cc, dd, ee, X[15], 8);
/* round 2 */
GG(ee, aa, bb, cc, dd, X[ 7], 7);
GG(dd, ee, aa, bb, cc, X[ 4], 6);
GG(cc, dd, ee, aa, bb, X[13], 8);
GG(bb, cc, dd, ee, aa, X[ 1], 13);
GG(aa, bb, cc, dd, ee, X[10], 11);
GG(ee, aa, bb, cc, dd, X[ 6], 9);
GG(dd, ee, aa, bb, cc, X[15], 7);
GG(cc, dd, ee, aa, bb, X[ 3], 15);
GG(bb, cc, dd, ee, aa, X[12], 7);
GG(aa, bb, cc, dd, ee, X[ 0], 12);
GG(ee, aa, bb, cc, dd, X[ 9], 15);
GG(dd, ee, aa, bb, cc, X[ 5], 9);
GG(cc, dd, ee, aa, bb, X[ 2], 11);
GG(bb, cc, dd, ee, aa, X[14], 7);
GG(aa, bb, cc, dd, ee, X[11], 13);
GG(ee, aa, bb, cc, dd, X[ 8], 12);
/* round 3 */
HH(dd, ee, aa, bb, cc, X[ 3], 11);
HH(cc, dd, ee, aa, bb, X[10], 13);
HH(bb, cc, dd, ee, aa, X[14], 6);
HH(aa, bb, cc, dd, ee, X[ 4], 7);
HH(ee, aa, bb, cc, dd, X[ 9], 14);
HH(dd, ee, aa, bb, cc, X[15], 9);
HH(cc, dd, ee, aa, bb, X[ 8], 13);
HH(bb, cc, dd, ee, aa, X[ 1], 15);
HH(aa, bb, cc, dd, ee, X[ 2], 14);
HH(ee, aa, bb, cc, dd, X[ 7], 8);
HH(dd, ee, aa, bb, cc, X[ 0], 13);
HH(cc, dd, ee, aa, bb, X[ 6], 6);
HH(bb, cc, dd, ee, aa, X[13], 5);
HH(aa, bb, cc, dd, ee, X[11], 12);
HH(ee, aa, bb, cc, dd, X[ 5], 7);
HH(dd, ee, aa, bb, cc, X[12], 5);
/* round 4 */
II(cc, dd, ee, aa, bb, X[ 1], 11);
II(bb, cc, dd, ee, aa, X[ 9], 12);
II(aa, bb, cc, dd, ee, X[11], 14);
II(ee, aa, bb, cc, dd, X[10], 15);
II(dd, ee, aa, bb, cc, X[ 0], 14);
II(cc, dd, ee, aa, bb, X[ 8], 15);
II(bb, cc, dd, ee, aa, X[12], 9);
II(aa, bb, cc, dd, ee, X[ 4], 8);
II(ee, aa, bb, cc, dd, X[13], 9);
II(dd, ee, aa, bb, cc, X[ 3], 14);
II(cc, dd, ee, aa, bb, X[ 7], 5);
II(bb, cc, dd, ee, aa, X[15], 6);
II(aa, bb, cc, dd, ee, X[14], 8);
II(ee, aa, bb, cc, dd, X[ 5], 6);
II(dd, ee, aa, bb, cc, X[ 6], 5);
II(cc, dd, ee, aa, bb, X[ 2], 12);
/* round 5 */
JJ(bb, cc, dd, ee, aa, X[ 4], 9);
JJ(aa, bb, cc, dd, ee, X[ 0], 15);
JJ(ee, aa, bb, cc, dd, X[ 5], 5);
JJ(dd, ee, aa, bb, cc, X[ 9], 11);
JJ(cc, dd, ee, aa, bb, X[ 7], 6);
JJ(bb, cc, dd, ee, aa, X[12], 8);
JJ(aa, bb, cc, dd, ee, X[ 2], 13);
JJ(ee, aa, bb, cc, dd, X[10], 12);
JJ(dd, ee, aa, bb, cc, X[14], 5);
JJ(cc, dd, ee, aa, bb, X[ 1], 12);
JJ(bb, cc, dd, ee, aa, X[ 3], 13);
JJ(aa, bb, cc, dd, ee, X[ 8], 14);
JJ(ee, aa, bb, cc, dd, X[11], 11);
JJ(dd, ee, aa, bb, cc, X[ 6], 8);
JJ(cc, dd, ee, aa, bb, X[15], 5);
JJ(bb, cc, dd, ee, aa, X[13], 6);
/* parallel round 1 */
JJJ(aaa, bbb, ccc, ddd, eee, X[ 5], 8);
JJJ(eee, aaa, bbb, ccc, ddd, X[14], 9);
JJJ(ddd, eee, aaa, bbb, ccc, X[ 7], 9);
JJJ(ccc, ddd, eee, aaa, bbb, X[ 0], 11);
JJJ(bbb, ccc, ddd, eee, aaa, X[ 9], 13);
JJJ(aaa, bbb, ccc, ddd, eee, X[ 2], 15);
JJJ(eee, aaa, bbb, ccc, ddd, X[11], 15);
JJJ(ddd, eee, aaa, bbb, ccc, X[ 4], 5);
JJJ(ccc, ddd, eee, aaa, bbb, X[13], 7);
JJJ(bbb, ccc, ddd, eee, aaa, X[ 6], 7);
JJJ(aaa, bbb, ccc, ddd, eee, X[15], 8);
JJJ(eee, aaa, bbb, ccc, ddd, X[ 8], 11);
JJJ(ddd, eee, aaa, bbb, ccc, X[ 1], 14);
JJJ(ccc, ddd, eee, aaa, bbb, X[10], 14);
JJJ(bbb, ccc, ddd, eee, aaa, X[ 3], 12);
JJJ(aaa, bbb, ccc, ddd, eee, X[12], 6);
/* parallel round 2 */
III(eee, aaa, bbb, ccc, ddd, X[ 6], 9);
III(ddd, eee, aaa, bbb, ccc, X[11], 13);
III(ccc, ddd, eee, aaa, bbb, X[ 3], 15);
III(bbb, ccc, ddd, eee, aaa, X[ 7], 7);
III(aaa, bbb, ccc, ddd, eee, X[ 0], 12);
III(eee, aaa, bbb, ccc, ddd, X[13], 8);
III(ddd, eee, aaa, bbb, ccc, X[ 5], 9);
III(ccc, ddd, eee, aaa, bbb, X[10], 11);
III(bbb, ccc, ddd, eee, aaa, X[14], 7);
III(aaa, bbb, ccc, ddd, eee, X[15], 7);
III(eee, aaa, bbb, ccc, ddd, X[ 8], 12);
III(ddd, eee, aaa, bbb, ccc, X[12], 7);
III(ccc, ddd, eee, aaa, bbb, X[ 4], 6);
III(bbb, ccc, ddd, eee, aaa, X[ 9], 15);
III(aaa, bbb, ccc, ddd, eee, X[ 1], 13);
III(eee, aaa, bbb, ccc, ddd, X[ 2], 11);
/* parallel round 3 */
HHH(ddd, eee, aaa, bbb, ccc, X[15], 9);
HHH(ccc, ddd, eee, aaa, bbb, X[ 5], 7);
HHH(bbb, ccc, ddd, eee, aaa, X[ 1], 15);
HHH(aaa, bbb, ccc, ddd, eee, X[ 3], 11);
HHH(eee, aaa, bbb, ccc, ddd, X[ 7], 8);
HHH(ddd, eee, aaa, bbb, ccc, X[14], 6);
HHH(ccc, ddd, eee, aaa, bbb, X[ 6], 6);
HHH(bbb, ccc, ddd, eee, aaa, X[ 9], 14);
HHH(aaa, bbb, ccc, ddd, eee, X[11], 12);
HHH(eee, aaa, bbb, ccc, ddd, X[ 8], 13);
HHH(ddd, eee, aaa, bbb, ccc, X[12], 5);
HHH(ccc, ddd, eee, aaa, bbb, X[ 2], 14);
HHH(bbb, ccc, ddd, eee, aaa, X[10], 13);
HHH(aaa, bbb, ccc, ddd, eee, X[ 0], 13);
HHH(eee, aaa, bbb, ccc, ddd, X[ 4], 7);
HHH(ddd, eee, aaa, bbb, ccc, X[13], 5);
/* parallel round 4 */
GGG(ccc, ddd, eee, aaa, bbb, X[ 8], 15);
GGG(bbb, ccc, ddd, eee, aaa, X[ 6], 5);
GGG(aaa, bbb, ccc, ddd, eee, X[ 4], 8);
GGG(eee, aaa, bbb, ccc, ddd, X[ 1], 11);
GGG(ddd, eee, aaa, bbb, ccc, X[ 3], 14);
GGG(ccc, ddd, eee, aaa, bbb, X[11], 14);
GGG(bbb, ccc, ddd, eee, aaa, X[15], 6);
GGG(aaa, bbb, ccc, ddd, eee, X[ 0], 14);
GGG(eee, aaa, bbb, ccc, ddd, X[ 5], 6);
GGG(ddd, eee, aaa, bbb, ccc, X[12], 9);
GGG(ccc, ddd, eee, aaa, bbb, X[ 2], 12);
GGG(bbb, ccc, ddd, eee, aaa, X[13], 9);
GGG(aaa, bbb, ccc, ddd, eee, X[ 9], 12);
GGG(eee, aaa, bbb, ccc, ddd, X[ 7], 5);
GGG(ddd, eee, aaa, bbb, ccc, X[10], 15);
GGG(ccc, ddd, eee, aaa, bbb, X[14], 8);
/* parallel round 5 */
FFF(bbb, ccc, ddd, eee, aaa, X[12] , 8);
FFF(aaa, bbb, ccc, ddd, eee, X[15] , 5);
FFF(eee, aaa, bbb, ccc, ddd, X[10] , 12);
FFF(ddd, eee, aaa, bbb, ccc, X[ 4] , 9);
FFF(ccc, ddd, eee, aaa, bbb, X[ 1] , 12);
FFF(bbb, ccc, ddd, eee, aaa, X[ 5] , 5);
FFF(aaa, bbb, ccc, ddd, eee, X[ 8] , 14);
FFF(eee, aaa, bbb, ccc, ddd, X[ 7] , 6);
FFF(ddd, eee, aaa, bbb, ccc, X[ 6] , 8);
FFF(ccc, ddd, eee, aaa, bbb, X[ 2] , 13);
FFF(bbb, ccc, ddd, eee, aaa, X[13] , 6);
FFF(aaa, bbb, ccc, ddd, eee, X[14] , 5);
FFF(eee, aaa, bbb, ccc, ddd, X[ 0] , 15);
FFF(ddd, eee, aaa, bbb, ccc, X[ 3] , 13);
FFF(ccc, ddd, eee, aaa, bbb, X[ 9] , 11);
FFF(bbb, ccc, ddd, eee, aaa, X[11] , 11);
/* combine results */
ddd += cc + md->rmd160.state[1]; /* final result for md->rmd160.state[0] */
md->rmd160.state[1] = md->rmd160.state[2] + dd + eee;
md->rmd160.state[2] = md->rmd160.state[3] + ee + aaa;
md->rmd160.state[3] = md->rmd160.state[4] + aa + bbb;
md->rmd160.state[4] = md->rmd160.state[0] + bb + ccc;
md->rmd160.state[0] = ddd;
}
#ifdef CLEAN_STACK
static void rmd160_compress(hash_state *md)
{
_rmd160_compress(md);
burn_stack(sizeof(unsigned long) * 26 + sizeof(int));
}
#endif
void rmd160_init(hash_state * md)
{
_ARGCHK(md != NULL);
md->rmd160.state[0] = 0x67452301UL;
md->rmd160.state[1] = 0xefcdab89UL;
md->rmd160.state[2] = 0x98badcfeUL;
md->rmd160.state[3] = 0x10325476UL;
md->rmd160.state[4] = 0xc3d2e1f0UL;
md->rmd160.curlen = 0;
md->rmd160.length = 0;
}
void rmd160_process(hash_state * md, const unsigned char *buf, unsigned long len)
{
unsigned long n;
_ARGCHK(md != NULL);
_ARGCHK(buf != NULL);
while (len > 0) {
n = MIN(len, (64 - md->rmd160.curlen));
memcpy(md->rmd160.buf + md->rmd160.curlen, buf, (size_t)n);
md->rmd160.curlen += n;
buf += n;
len -= n;
/* is 64 bytes full? */
if (md->rmd160.curlen == 64) {
rmd160_compress(md);
md->rmd160.length += 512;
md->rmd160.curlen = 0;
}
}
}
void rmd160_done(hash_state * md, unsigned char *hash)
{
int i;
_ARGCHK(md != NULL);
_ARGCHK(hash != NULL);
/* increase the length of the message */
md->rmd160.length += md->rmd160.curlen * 8;
/* append the '1' bit */
md->rmd160.buf[md->rmd160.curlen++] = (unsigned char)0x80;
/* if the length is currently above 56 bytes we append zeros
* then compress. Then we can fall back to padding zeros and length
* encoding like normal.
*/
if (md->rmd160.curlen > 56) {
while (md->rmd160.curlen < 64) {
md->rmd160.buf[md->rmd160.curlen++] = (unsigned char)0;
}
rmd160_compress(md);
md->rmd160.curlen = 0;
}
/* pad upto 56 bytes of zeroes */
while (md->rmd160.curlen < 56) {
md->rmd160.buf[md->rmd160.curlen++] = (unsigned char)0;
}
/* store length */
STORE64L(md->rmd160.length, md->rmd160.buf+56);
rmd160_compress(md);
/* copy output */
for (i = 0; i < 5; i++) {
STORE32L(md->rmd160.state[i], hash+(4*i));
}
#ifdef CLEAN_STACK
zeromem(md, sizeof(hash_state));
#endif
}
int rmd160_test(void)
{
static const struct {
char *msg;
unsigned char md[20];
} tests[] = {
{ "",
{ 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28,
0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 }
},
{ "a",
{ 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae,
0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe }
},
{ "abc",
{ 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04,
0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc }
},
{ "message digest",
{ 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8,
0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 }
},
{ "abcdefghijklmnopqrstuvwxyz",
{ 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb,
0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc }
},
{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
{ 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05,
0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b }
}
};
int x;
unsigned char buf[20];
hash_state md;
for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
rmd160_init(&md);
rmd160_process(&md, (unsigned char *)tests[x].msg, strlen(tests[x].msg));
rmd160_done(&md, buf);
if (memcmp(buf, tests[x].md, 20) != 0) {
#if 0
printf("Failed test %d\n", x);
#endif
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
}
#endif

BIN
tdcal.pdf

Binary file not shown.

View File

@ -1,9 +1,9 @@
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
* LibTomMath is library that provides for multiple-precision
* LibTomMath is a library that provides multiple-precision
* integer arithmetic as well as number theoretic functionality.
*
* The library is designed directly after the MPI library by
* The library was designed directly after the MPI library by
* Michael Fromberger but has been written from scratch with
* additional optimizations in place.
*
@ -82,8 +82,10 @@ extern "C" {
typedef ulong64 mp_word;
#ifdef MP_31BIT
/* this is an extension that uses 31-bit digits */
#define DIGIT_BIT 31
#else
/* default case is 28-bit digits, defines MP_28BIT as a handy macro to test */
#define DIGIT_BIT 28
#define MP_28BIT
#endif
@ -94,7 +96,6 @@ extern "C" {
#define DIGIT_BIT ((int)((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
@ -121,7 +122,7 @@ extern int KARATSUBA_MUL_CUTOFF,
TOOM_SQR_CUTOFF;
/* various build options */
#define MP_PREC 64 /* default digits of precision (must be power of two) */
#define MP_PREC 64 /* default digits of precision */
/* define this to use lower memory usage routines (exptmods mostly) */
/* #define MP_LOW_MEM */
@ -135,11 +136,13 @@ typedef struct {
} mp_int;
#define USED(m) ((m)->used)
#define DIGIT(m,k) ((m)->dp[k])
#define DIGIT(m,k) ((m)->dp[(k)])
#define SIGN(m) ((m)->sign)
/* ---> init and deinit bignum functions <--- */
/* error code to char* string */
char *mp_error_to_string(int code);
/* ---> init and deinit bignum functions <--- */
/* init a bignum */
int mp_init(mp_int *a);
@ -165,7 +168,6 @@ int mp_grow(mp_int *a, int size);
int mp_init_size(mp_int *a, int size);
/* ---> Basic Manipulations <--- */
#define mp_iszero(a) (((a)->used == 0) ? 1 : 0)
#define mp_iseven(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 0)) ? 1 : 0)
#define mp_isodd(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 1)) ? 1 : 0)
@ -462,5 +464,5 @@ extern const char *mp_s_rmap;
}
#endif
#endif
#endif /* ?BN_H_ */

View File

@ -123,7 +123,11 @@ int yarrow_ready(prng_state *prng)
return err;
}
if ((err = ctr_start(prng->yarrow.cipher, prng->yarrow.pool, prng->yarrow.pool, ks, 0, &prng->yarrow.ctr)) != CRYPT_OK) {
if ((err = ctr_start(prng->yarrow.cipher, /* what cipher to use */
prng->yarrow.pool, /* IV */
prng->yarrow.pool, ks, /* KEY and key size */
0, /* number of rounds */
&prng->yarrow.ctr)) != CRYPT_OK) {
return err;
}
return CRYPT_OK;