From 1c1822d51064f093d5dededb6e976190dd19bd47 Mon Sep 17 00:00:00 2001 From: Tom St Denis Date: Sat, 30 Oct 2004 03:00:26 +0000 Subject: [PATCH] added libtomcrypt-0.99 --- LICENSE | 2 +- changes | 28 + chc.c | 261 ++++++ crypt | 25 - crypt.c | 3 + crypt.tex | 425 +++++++--- cscope.tmplst | 219 +++++ demos/hashsum.c | 13 +- demos/test/cipher_hash_test.c | 6 +- demos/test/der_tests.c | 82 ++ demos/test/dh_tests.c | 12 + demos/test/dsa_test.c | 16 +- demos/test/ecc_test.c | 12 + demos/test/makefile | 6 +- demos/test/makefile.icc | 2 +- demos/test/makefile.msvc | 2 +- demos/test/makefile.shared | 19 + demos/test/pkcs_1_test.c | 13 + demos/test/rsa_test.c | 77 +- demos/test/test.c | 57 +- demos/test/test.h | 1 + demos/tv_gen.c | 14 +- demos/tv_gen.lo | 12 + demos/x86_prof.c | 15 +- der_decode_integer.c | 83 ++ der_encode_integer.c | 93 +++ der_get_multi_integer.c | 50 ++ der_length_integer.c | 54 ++ der_put_multi_integer.c | 49 ++ doc/crypt.pdf | Bin 392972 -> 403993 bytes ecc.c | 11 +- fortuna.c | 4 +- hash_filehandle.c | 6 +- hash_memory.c | 4 +- hmac_done.c | 4 +- hmac_init.c | 5 +- ltc_tommath.h | 32 +- makefile | 33 +- makefile.cygwin_dll | 14 +- makefile.icc | 6 +- makefile.msvc | 8 +- makefile.shared | 186 +++++ md2.c | 3 +- md4.c | 15 +- md5.c | 15 +- mpi.c | 1451 ++++++++++++++++++--------------- mycrypt.h | 4 +- mycrypt_argchk.h | 2 +- mycrypt_cfg.h | 6 + mycrypt_custom.h | 21 +- mycrypt_hash.h | 81 +- mycrypt_macros.h | 34 +- mycrypt_pk.h | 11 +- mycrypt_prng.h | 4 +- notes/hash_tv.txt | 35 + notes/hmac_tv.txt | 35 + omac_done.c | 12 +- omac_test.c | 5 +- pkcs_1_mgf1.c | 4 +- pkcs_1_pss_decode.c | 4 +- pkcs_1_pss_encode.c | 4 +- pkcs_5_1.c | 4 +- rmd128.c | 15 +- rmd160.c | 15 +- rsa_export.c | 65 +- rsa_exptmod.c | 23 +- rsa_free.c | 2 +- rsa_import.c | 74 +- rsa_make_key.c | 13 +- sha1.c | 15 +- sha224.c | 3 +- sha256.c | 15 +- sha384.c | 3 +- sha512.c | 16 +- sober128.c | 2 +- tiger.c | 15 +- tommath_class.h | 955 ++++++++++++++++++++++ tommath_superclass.h | 70 ++ whirl.c | 17 +- yarrow.c | 6 +- 80 files changed, 3942 insertions(+), 1096 deletions(-) create mode 100644 chc.c delete mode 100644 crypt create mode 100644 cscope.tmplst create mode 100644 demos/test/der_tests.c create mode 100644 demos/test/makefile.shared create mode 100644 demos/tv_gen.lo create mode 100644 der_decode_integer.c create mode 100644 der_encode_integer.c create mode 100644 der_get_multi_integer.c create mode 100644 der_length_integer.c create mode 100644 der_put_multi_integer.c create mode 100644 makefile.shared create mode 100644 tommath_class.h create mode 100644 tommath_superclass.h diff --git a/LICENSE b/LICENSE index 2e83cda..50e7435 100644 --- a/LICENSE +++ b/LICENSE @@ -2,7 +2,7 @@ LibTomCrypt is public domain. As should all quality software be. All of the software was either written by or donated to Tom St Denis for the purposes of this project. The only exception is the SAFER.C source which has no known -license status (assumed copyrighted) which is why SAFER,C is shipped as disabled. +license status (assumed copyrighted) which is why SAFER.C is shipped as disabled. Tom St Denis diff --git a/changes b/changes index cd5ef23..f887acf 100644 --- a/changes +++ b/changes @@ -1,3 +1,31 @@ +October 29th, 2004 +v0.99 -- Merged in the latest version of LTM which includes all of the recent bug fixes + -- Deprecated LTMSSE and removed it (to be replaced with TFM later on) + -- Stefan Arentz pointed out that mp_s_rmap should be extern + -- Kristian Gjøsteen pointed out that there are typos in the + "test" makefile and minor issues in Yarrow and Sober [just cosmetics really] + -- Matthew P. Cashdollar pointed out that "export" is a C++ keyword + so changed the PRNG api to use "pexport" and "pimport" + -- Updated "hashsum" demo so it builds ;-) + -- Added automatic support for x86-64 (will configure for 64-bit little endian automagically) + -- Zhi Chen pointed out a bug in rsa_exptmod which would leak memory on error. + -- Made hash functions "init" return an int. slight change to API ;-( + -- Added "CHC" mode which turns any cipher into a hash the other LTC functions can use + -- Added CHC mode stuff to demos such as tv_gen and hashsum + -- Added "makefile.shared" which builds and installs shared/static object copies + of the library. + -- Added DER for bignum support + -- RSA is now fully joy. rsa_export/rsa_import use PKCS #1 encodings and should be + compatible with other crypto libs that use the format. + -- Added support for x86-64 for the ROL/ROR macros + -- Changed the DLL and SO makefiles to optimize for speed, commented SMALL_CODE in + mycrypt_custom.h and added -DSMALL_CODE to the default makefile + -- Updated primality testing code so it does a minimum of 5 tests [of Miller-Rabin] + (AFAIK not a security fix, just warm fuzzies) + -- Minor updates to the OMAC code (additional __ARGCHK and removed printf from omac_test... oops!) + -- Update build and configuration info which was really really really out of date. (Chapter 14) + ++ Minor update, switch RSA to use the PKCS style CRT + August 6th, 2004 v0.98 -- Update to hmac_init to free all allocated memory on error -- Update to PRNG API to fix import/export functions of Fortuna and Yarrow diff --git a/chc.c b/chc.c new file mode 100644 index 0000000..e144b68 --- /dev/null +++ b/chc.c @@ -0,0 +1,261 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + */ + +#include "mycrypt.h" + +#ifdef CHC_HASH + +#define UNDEFED_HASH -17 + +/* chc settings */ +static int cipher_idx=UNDEFED_HASH, /* which cipher */ + cipher_blocksize; /* blocksize of cipher */ + + +const struct _hash_descriptor chc_desc = { + "chc_hash", 12, 0, 0, { 0 }, 0, + &chc_init, + &chc_process, + &chc_done, + &chc_test +}; + +/* initialize the CHC state with a given cipher */ +int chc_register(int cipher) +{ + int err, kl, idx; + + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + + /* will it be valid? */ + kl = cipher_descriptor[cipher].block_length; + + /* must be >64 bit block */ + if (kl <= 8) { + return CRYPT_INVALID_CIPHER; + } + + /* can we use the ideal keysize? */ + if ((err = cipher_descriptor[cipher].keysize(&kl)) != CRYPT_OK) { + return err; + } + /* we require that key size == block size be a valid choice */ + if (kl != cipher_descriptor[cipher].block_length) { + return CRYPT_INVALID_CIPHER; + } + + /* determine if chc_hash has been register_hash'ed already */ + if ((err = hash_is_valid(idx = find_hash("chc_hash"))) != CRYPT_OK) { + return err; + } + + /* store into descriptor */ + hash_descriptor[idx].hashsize = + hash_descriptor[idx].blocksize = cipher_descriptor[cipher].block_length; + + /* store the idx and block size */ + cipher_idx = cipher; + cipher_blocksize = cipher_descriptor[cipher].block_length; + return CRYPT_OK; +} + +/* "hash init" is simply encrypt 0 with the 0 key. Simple way to make an IV */ +int chc_init(hash_state *md) +{ + symmetric_key *key; + unsigned char buf[MAXBLOCKSIZE]; + int err; + + _ARGCHK(md != NULL); + + /* is the cipher valid? */ + if ((err = cipher_is_valid(cipher_idx)) != CRYPT_OK) { + return err; + } + + if (cipher_blocksize != cipher_descriptor[cipher_idx].block_length) { + return CRYPT_INVALID_CIPHER; + } + + if ((key = XMALLOC(sizeof(*key))) == NULL) { + return CRYPT_MEM; + } + + /* zero key and what not */ + zeromem(buf, cipher_blocksize); + if ((err = cipher_descriptor[cipher_idx].setup(buf, cipher_blocksize, 0, key)) != CRYPT_OK) { + XFREE(key); + return err; + } + + /* encrypt zero block */ + cipher_descriptor[cipher_idx].ecb_encrypt(buf, md->chc.state, key); + + /* zero other members */ + md->chc.length = 0; + md->chc.curlen = 0; + zeromem(md->chc.buf, sizeof(md->chc.buf)); + XFREE(key); + return CRYPT_OK; +} + +/* + key <= state + T0,T1 <= block + T0 <= encrypt T0 + state <= state xor T0 xor T1 +*/ +static int chc_compress(hash_state *md, unsigned char *buf) +{ + unsigned char T[2][MAXBLOCKSIZE]; + symmetric_key *key; + int err, x; + + if ((key = XMALLOC(sizeof(*key))) == NULL) { + return CRYPT_MEM; + } + if ((err = cipher_descriptor[cipher_idx].setup(md->chc.state, cipher_blocksize, 0, key)) != CRYPT_OK) { + XFREE(key); + return err; + } + memcpy(T[1], buf, cipher_blocksize); + cipher_descriptor[cipher_idx].ecb_encrypt(buf, T[0], key); + for (x = 0; x < cipher_blocksize; x++) { + md->chc.state[x] ^= T[0][x] ^ T[1][x]; + } + XFREE(key); +#ifdef CLEAN_STACK + zeromem(T, sizeof(T)); + zeromem(&key, sizeof(key)); +#endif + return CRYPT_OK; +} + +HASH_PROCESS(_chc_process, chc_compress, chc, (unsigned long)cipher_blocksize) + +int chc_process(hash_state * md, const unsigned char *buf, unsigned long len) +{ + int err; + + _ARGCHK(md != NULL); + _ARGCHK(buf != NULL); + + /* is the cipher valid? */ + if ((err = cipher_is_valid(cipher_idx)) != CRYPT_OK) { + return err; + } + if (cipher_blocksize != cipher_descriptor[cipher_idx].block_length) { + return CRYPT_INVALID_CIPHER; + } + + return _chc_process(md, buf, len); +} + +int chc_done(hash_state *md, unsigned char *buf) +{ + int err; + + _ARGCHK(md != NULL); + _ARGCHK(buf != NULL); + + /* is the cipher valid? */ + if ((err = cipher_is_valid(cipher_idx)) != CRYPT_OK) { + return err; + } + if (cipher_blocksize != cipher_descriptor[cipher_idx].block_length) { + return CRYPT_INVALID_CIPHER; + } + + if (md->chc.curlen >= sizeof(md->chc.buf)) { + return CRYPT_INVALID_ARG; + } + + /* increase the length of the message */ + md->chc.length += md->chc.curlen * 8; + + /* append the '1' bit */ + md->chc.buf[md->chc.curlen++] = (unsigned char)0x80; + + /* if the length is currently above l-8 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md->chc.curlen > (unsigned long)(cipher_blocksize - 8)) { + while (md->chc.curlen < (unsigned long)cipher_blocksize) { + md->chc.buf[md->chc.curlen++] = (unsigned char)0; + } + chc_compress(md, md->chc.buf); + md->chc.curlen = 0; + } + + /* pad upto l-8 bytes of zeroes */ + while (md->chc.curlen < (unsigned long)(cipher_blocksize - 8)) { + md->chc.buf[md->chc.curlen++] = (unsigned char)0; + } + + /* store length */ + STORE64L(md->chc.length, md->chc.buf+(cipher_blocksize-8)); + chc_compress(md, md->chc.buf); + + /* copy output */ + XMEMCPY(buf, md->chc.state, cipher_blocksize); + +#ifdef CLEAN_STACK + zeromem(md, sizeof(hash_state)); +#endif + return CRYPT_OK; +} + +int chc_test(void) +{ + static const struct { + unsigned char *msg, + md[MAXBLOCKSIZE]; + int len; + } tests[] = { +{ + (unsigned char *)"hello world", + { 0xcf, 0x57, 0x9d, 0xc3, 0x0a, 0x0e, 0xea, 0x61, + 0x0d, 0x54, 0x47, 0xc4, 0x3c, 0x06, 0xf5, 0x4e }, + 16 +} +}; + int x, oldhashidx, idx; + unsigned char out[MAXBLOCKSIZE]; + hash_state md; + + /* AES can be under rijndael or aes... try to find it */ + if ((idx = find_cipher("aes")) == -1) { + if ((idx = find_cipher("rijndael")) == -1) { + return CRYPT_NOP; + } + } + oldhashidx = cipher_idx; + chc_register(idx); + + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { + chc_init(&md); + chc_process(&md, tests[x].msg, strlen((char *)tests[x].msg)); + chc_done(&md, out); + if (memcmp(out, tests[x].md, tests[x].len)) { + return CRYPT_FAIL_TESTVECTOR; + } + } + if (oldhashidx != UNDEFED_HASH) { + chc_register(oldhashidx); + } + + return CRYPT_OK; +} + +#endif diff --git a/crypt b/crypt deleted file mode 100644 index 88a14ee..0000000 --- a/crypt +++ /dev/null @@ -1,25 +0,0 @@ -%PDF-1.3 -%Ç쏢 -3 0 obj -<< /Type /Pages /Kids [ -] /Count 0 ->> -endobj -1 0 obj -<> -endobj -2 0 obj -<>endobj -xref -0 4 -0000000000 65535 f -0000000068 00000 n -0000000116 00000 n -0000000015 00000 n -trailer -<< /Size 4 /Root 1 0 R /Info 2 0 R ->> -startxref -166 -%%EOF diff --git a/crypt.c b/crypt.c index 56b5c5a..3a4bdc3 100644 --- a/crypt.c +++ b/crypt.c @@ -123,6 +123,9 @@ const char *crypt_build_settings = #if defined(WHIRLPOOL) " WHIRLPOOL\n" #endif +#if defined(CHC_HASH) + " CHC_HASH \n" +#endif "\nBlock Chaining Modes:\n" #if defined(CFB) diff --git a/crypt.tex b/crypt.tex index 875d903..b8acb3f 100644 --- a/crypt.tex +++ b/crypt.tex @@ -47,7 +47,7 @@ \def\gap{\vspace{0.5ex}} \makeindex \begin{document} -\title{LibTomCrypt \\ Version 0.98} +\title{LibTomCrypt \\ Version 0.99} \author{Tom St Denis \\ \\ tomstdenis@iahu.ca \\ @@ -199,24 +199,6 @@ of the ciphers and hashes are patent free or under patents that have since expir The RC2 and RC4 symmetric ciphers are not under patents but are under trademark regulations. This means you can use the ciphers you just can't advertise that you are doing so. -\section{Building the library} - -To build the library on a GCC equipped platform simply type ``make'' at your command prompt. It will build the library -file ``libtomcrypt.a''. - -To install the library copy all of the ``.h'' files into your ``\#include'' path and the single libtomcrypt.a file into -your library path. - -With MSVC you can build the library with ``nmake -f makefile.msvc''. This will produce a ``tomcrypt.lib'' file which -is the core library. Copy the header files into your MSVC include path and the library in the lib path (typically -under where VC98 is installed). - -\section{Building against the library} - -In the recent versions the build steps have changed. The build options are now stored in ``mycrypt\_custom.h'' and -no longer in the makefile. If you change a build option in that file you must re-build the library from clean to -ensure the build is intact. - \section{Thanks} I would like to give thanks to the following people (in no particular order) for helping me develop this project from early on: @@ -1354,7 +1336,60 @@ int register_hash(const struct _hash_descriptor *hash); int unregister_hash(const struct _hash_descriptor *hash); \end{verbatim} -\subsection{Notice} +\section{Cipher Hash Construction} +\index{Cipher Hash Construction} +An addition to the suite of hash functions is the ``Cipher Hash Construction'' or ``CHC'' mode. In this mode +applicable block ciphers (such as AES) can be turned into hash functions that other LTC functions can use. In +particular this allows a cryptosystem to be designed using very few moving parts. + +In order to use the CHC system the developer will have to take a few extra steps. First the ``chc\_desc'' hash +descriptor must be registered with register\_hash(). At this point the CHC hash cannot be used to hash +data. While it is in the hash system you still have to tell the CHC code which cipher to use. This is accomplished +via the chc\_register() function. + +\index{chc\_register()} +\begin{verbatim} +int chc_register(int cipher); +\end{verbatim} + +A cipher has to be registered with CHC (and also in the cipher descriptor tables with +register\_cipher()). The chc\_register() function will bind a cipher to the CHC system. Only one cipher can +be bound to the CHC hash at a time. There are additional requirements for the system to work. + +\begin{enumerate} + \item The cipher must have a block size greater than 64--bits. + \item The cipher must allow an input key the size of the block size. +\end{enumerate} + +Example of using CHC with the AES block cipher. + +\begin{verbatim} +#include +int main(void) +{ + int err; + + /* register cipher and hash */ + if (register_cipher(&aes_enc_desc) == -1) { + printf("Could not register cipher\n"); + return EXIT_FAILURE; + } + if (register_hash(&chc_desc) == -1) { + printf("Could not register hash\n"); + return EXIT_FAILURE; + } + + /* start chc with AES */ + if ((err = chc_register(find_cipher("aes"))) != CRYPT_OK) { + printf("Error binding AES to CHC: %s\n", error_to_string(err)); + } + + /* now you can use chc_hash in any LTC function [aside from pkcs...] */ + /* ... */ +\end{verbatim} + + +\section{Notice} 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). @@ -2260,10 +2295,11 @@ Note that the ``rsa\_make\_key()'' function allocates memory at runtime when you ``rsa\_free()'' (see below) when you are finished with the key. If ``rsa\_make\_key()'' fails it will automatically free the ram allocated itself. -There are three types of RSA keys. The types are {\bf PK\_PRIVATE\_OPTIMIZED}, {\bf PK\_PRIVATE} and {\bf PK\_PUBLIC}. The first -two are private keys where the ``optimized'' type uses the Chinese Remainder Theorem to speed up decryption/signatures. By -default all new keys are of the ``optimized'' type. The non-optimized private type is provided for backwards compatibility -as well as to save space since the optimized key requires about four times as much memory. +\index{PK\_PRIVATE} \index{PK\_PUBLIC} +There are two types of RSA keys. The types are {\bf PK\_PRIVATE} and {\bf PK\_PUBLIC}. The first type is a private +RSA key which includes the CRT parameters\footnote{As of v0.99 the PK\_PRIVATE\_OPTIMIZED type has been deprecated +and has been replaced by the PK\_PRIVATE type.} in the form of a RSAPrivateKey. The second type is a public RSA key +which only includes the modulus and public exponent. It takes the form of a RSAPublicKey. \subsection{RSA Exponentiation} @@ -2416,79 +2452,6 @@ int main(void) } \end{verbatim} -\chapter{Password Based Cryptography} -\section{PKCS \#5} -In order to securely handle user passwords for the purposes of creating session keys and chaining IVs the PKCS \#5 was drafted. PKCS \#5 -is made up of two algorithms, Algorithm One and Algorithm Two. Algorithm One is the older fairly limited algorithm which has been implemented -for completeness. Algorithm Two is a bit more modern and more flexible to work with. - -\section{Algorithm One} -Algorithm One accepts as input a password, an 8--byte salt and an iteration counter. The iteration counter is meant to act as delay for -people trying to brute force guess the password. The higher the iteration counter the longer the delay. This algorithm also requires a hash -algorithm and produces an output no longer than the output of the hash. - -\index{pkcs\_5\_alg1()} -\begin{alltt} -int pkcs_5_alg1(const unsigned char *password, unsigned long password_len, - const unsigned char *salt, - int iteration_count, int hash_idx, - unsigned char *out, unsigned long *outlen) -\end{alltt} -Where ``password'' is the users password. Since the algorithm allows binary passwords you must also specify the length in ``password\_len''. -The ``salt'' is a fixed size 8--byte array which should be random for each user and session. The ``iteration\_count'' is the delay desired -on the password. The ``hash\_idx'' is the index of the hash you wish to use in the descriptor table. - -The output of length upto ``outlen'' is stored in ``out''. If ``outlen'' is initially larger than the size of the hash functions output -it is set to the number of bytes stored. If it is smaller than not all of the hash output is stored in ``out''. - -\section{Algorithm Two} - -Algorithm Two is the recommended algorithm for this task. It allows variable length salts and can produce outputs larger than the -hash functions output. As such it can easily be used to derive session keys for ciphers and MACs as well initial vectors as required -from a single password and invokation of this algorithm. - -\index{pkcs\_5\_alg2()} -\begin{alltt} -int pkcs_5_alg2(const unsigned char *password, unsigned long password_len, - const unsigned char *salt, unsigned long salt_len, - int iteration_count, int hash_idx, - unsigned char *out, unsigned long *outlen) -\end{alltt} -Where ``password'' is the users password. Since the algorithm allows binary passwords you must also specify the length in ``password\_len''. -The ``salt'' is an array of size ``salt\_len''. It should be random for each user and session. The ``iteration\_count'' is the delay desired -on the password. The ``hash\_idx'' is the index of the hash you wish to use in the descriptor table. The output of length upto -``outlen'' is stored in ``out''. - -\begin{alltt} -/* demo to show how to make session state material from a password */ -#include -int main(void) -\{ - unsigned char password[100], salt[100], - cipher_key[16], cipher_iv[16], - mac_key[16], outbuf[48]; - int err, hash_idx; - unsigned long outlen, password_len, salt_len; - - /* register hash and get it's idx .... */ - - /* get users password and make up a salt ... */ - - /* create the material (100 iterations in algorithm) */ - outlen = sizeof(outbuf); - if ((err = pkcs_5_alg2(password, password_len, salt, salt_len, - 100, hash_idx, outbuf, &outlen)) != CRYPT_OK) \{ - /* error handle */ - \} - - /* now extract it */ - memcpy(cipher_key, outbuf, 16); - memcpy(cipher_iv, outbuf+16, 16); - memcpy(mac_key, outbuf+32, 16); - - /* use material (recall to store the salt in the output) */ -\} -\end{alltt} \chapter{Diffie-Hellman Key Exchange} @@ -2918,8 +2881,6 @@ int dsa_verify_key(dsa_key *key, int *stat); This will test ``key'' and store the result in ``stat''. If the result is $stat = 0$ the DSA key failed one of the tests and should not be used at all. If the result is $stat = 1$ the DSA key is valid (as far as valid mathematics are concerned). - - \section{Signatures} To generate a DSA signature call the following function @@ -2969,6 +2930,153 @@ int dsa_import(const unsigned char *in, unsigned long inlen, This will import the DSA key from the buffer ``in'' of length ``inlen'' to the ``key''. If the process fails the function will automatically free all of the heap allocated in the process (you don't have to call dsa\_free()). +\chapter{Standards Support} +\section{DER Support} +DER or ``Distinguished Encoding Rules'' is a subset of the ASN.1 encoding rules that is fully deterministic and +ideal for cryptography. In particular ASN.1 specifies an INTEGER type for storing arbitrary sized integers. DER +further limits the ASN.1 specifications to a deterministic encoding. + +\subsection{Storing INTEGER types} +\index{der\_encode\_integer()} +\begin{alltt} +int der_encode_integer(mp_int *num, unsigned char *out, unsigned long *outlen); +\end{alltt} + +This will store the integer in ``num'' to the output buffer ``out'' of length ``outlen''. It only stores +non--negative numbers. It stores the number of octets used back in ``outlen''. + +\subsection{Reading INTEGER types} +\index{der\_decode\_integer()} +\begin{alltt} +int der_decode_integer(const unsigned char *in, unsigned long *inlen, mp_int *num); +\end{alltt} +This will decode the DER encoded INTEGER in ``in'' of length ``inlen'' and store the resulting integer +in ``num''. It will store the bytes read in ``inlen'' which is handy if you have to parse multiple +data items out of a binary packet. + +\subsection{INTEGER length} +\index{der\_length\_integer()} +\begin{alltt} +int der_length_integer(mp_int *num, unsigned long *len); +\end{alltt} +This will determine the length of the DER encoding of the integer ``num'' and store it in ``len''. + +\subsection{Multiple INTEGER types} +To simplify the DER encoding/decoding there are two functions two handle multple types at once. + +\index{der\_put\_multi\_integer()} +\index{der\_get\_multi\_integer()} +\begin{alltt} +int der_put_multi_integer(unsigned char *dst, unsigned long *outlen, mp_int *num, ...); +int der_get_multi_integer(const unsigned char *src, unsigned long *inlen, mp_int *num, ...); +\end{alltt} + +These will handle multiple encodings/decodings at once. They work like their single operand counterparts +except they handle a \textbf{NULL} terminated list of operands. + +\begin{verbatim} +#include +int main(void) +{ + mp_int a, b, c, d; + unsigned char buffer[1000]; + unsigned long len; + int err; + + /* init a,b,c,d with some values ... */ + + /* ok we want to store them now... */ + len = sizeof(buffer); + if ((err = der_put_multi_integer(buffer, &len, + &a, &b, &c, &d, NULL)) != CRYPT_OK) { + // error + } + printf("I stored %lu bytes in buf\n", len); + + /* ok say we want to get them back for fun */ + /* len set previously...otherwise set it to the size of the packet */ + if ((err = der_get_multi_integer(buffer, &len, + &a, &b, &c, &d, NULL)) != CRYPT_OK) { + // error + } + printf("I read %lu bytes from buf\n", len); +} +\end{verbatim} +\section{Password Based Cryptography} +\subsection{PKCS \#5} +In order to securely handle user passwords for the purposes of creating session keys and chaining IVs the PKCS \#5 was drafted. PKCS \#5 +is made up of two algorithms, Algorithm One and Algorithm Two. Algorithm One is the older fairly limited algorithm which has been implemented +for completeness. Algorithm Two is a bit more modern and more flexible to work with. + +\subsection{Algorithm One} +Algorithm One accepts as input a password, an 8--byte salt and an iteration counter. The iteration counter is meant to act as delay for +people trying to brute force guess the password. The higher the iteration counter the longer the delay. This algorithm also requires a hash +algorithm and produces an output no longer than the output of the hash. + +\index{pkcs\_5\_alg1()} +\begin{alltt} +int pkcs_5_alg1(const unsigned char *password, unsigned long password_len, + const unsigned char *salt, + int iteration_count, int hash_idx, + unsigned char *out, unsigned long *outlen) +\end{alltt} +Where ``password'' is the users password. Since the algorithm allows binary passwords you must also specify the length in ``password\_len''. +The ``salt'' is a fixed size 8--byte array which should be random for each user and session. The ``iteration\_count'' is the delay desired +on the password. The ``hash\_idx'' is the index of the hash you wish to use in the descriptor table. + +The output of length upto ``outlen'' is stored in ``out''. If ``outlen'' is initially larger than the size of the hash functions output +it is set to the number of bytes stored. If it is smaller than not all of the hash output is stored in ``out''. + +\subsection{Algorithm Two} + +Algorithm Two is the recommended algorithm for this task. It allows variable length salts and can produce outputs larger than the +hash functions output. As such it can easily be used to derive session keys for ciphers and MACs as well initial vectors as required +from a single password and invokation of this algorithm. + +\index{pkcs\_5\_alg2()} +\begin{alltt} +int pkcs_5_alg2(const unsigned char *password, unsigned long password_len, + const unsigned char *salt, unsigned long salt_len, + int iteration_count, int hash_idx, + unsigned char *out, unsigned long *outlen) +\end{alltt} +Where ``password'' is the users password. Since the algorithm allows binary passwords you must also specify the length in ``password\_len''. +The ``salt'' is an array of size ``salt\_len''. It should be random for each user and session. The ``iteration\_count'' is the delay desired +on the password. The ``hash\_idx'' is the index of the hash you wish to use in the descriptor table. The output of length upto +``outlen'' is stored in ``out''. + +\begin{alltt} +/* demo to show how to make session state material from a password */ +#include +int main(void) +\{ + unsigned char password[100], salt[100], + cipher_key[16], cipher_iv[16], + mac_key[16], outbuf[48]; + int err, hash_idx; + unsigned long outlen, password_len, salt_len; + + /* register hash and get it's idx .... */ + + /* get users password and make up a salt ... */ + + /* create the material (100 iterations in algorithm) */ + outlen = sizeof(outbuf); + if ((err = pkcs_5_alg2(password, password_len, salt, salt_len, + 100, hash_idx, outbuf, &outlen)) != CRYPT_OK) \{ + /* error handle */ + \} + + /* now extract it */ + memcpy(cipher_key, outbuf, 16); + memcpy(cipher_iv, outbuf+16, 16); + memcpy(mac_key, outbuf+32, 16); + + /* use material (recall to store the salt in the output) */ +\} +\end{alltt} + + \chapter{Miscellaneous} \section{Base64 Encoding and Decoding} The library provides functions to encode and decode a RFC1521 base64 coding scheme. This means that it can decode what it @@ -3202,18 +3310,77 @@ possible as some compilers may ignore the ``volatile'' keyword or have multiple is modular enough putting the locks in the right place should not bloat the code significantly and will solve all thread safety issues within the library. -\chapter{Configuring the Library} +\chapter{Configuring and Building the Library} \section{Introduction} The library is fairly flexible about how it can be built, used and generally distributed. Additions are being made with -each new release that will make the library even more flexible. Most options are placed in the makefile and others -are in ``mycrypt\_cfg.h''. All are used when the library is built from scratch. +each new release that will make the library even more flexible. Each of the classes of functions can be disabled during +the build process to make a smaller library. This is particularly useful for shared libraries. -For GCC platforms the file ``makefile'' is the makefile to be used. On MSVC platforms ``makefile.vc'' and on PS2 platforms -``makefile.ps2''. +\section{Building a Static Library} +The library can be built as a static library which is generally the simplest and most portable method of +building the library. With a CC or GCC equipped platform you can issue the following + +\begin{alltt} +make install_lib +\end{alltt} + +Which will build the library and install it in /usr/lib (as well as the headers in /usr/include). The destination +directory of the library and headers can be changed by editing ``makefile''. The variable LIBNAME controls +where the library is to be installed and INCNAME controls where the headers are to be installed. A developer can +then use the library by including ``mycrypt.h'' in their program and linking against ``libtomcrypt.a''. + +A static library can also be built with the Intel C Compiler (ICC) by issuing the following + +\begin{alltt} +make -f makefile.icc install +\end{alltt} + +This will also build ``libtomcrypt.a'' except that it will use ICC. Additionally Microsoft's Visual C 6.00 can be used +by issuing + +\begin{alltt} +nmake -f makefile.msvc +\end{alltt} + +You will have to manually copy ``tomcrypt.lib'' and the headers to your MSVC lib/inc directories. + +\subsection{MPI Control} +If you already have LibTomMath installed you can safely remove it from the build. By commenting the line +in the appropriate makefile which starts with + +\begin{alltt} +MPIOBJECT=mpi +\end{alltt} + +Simply place a \# at the start and re-build the library. To properly link applications you will have to also +link in LibTomMath. Removing MPI has the benefit of cutting down the library size as well potentially have access +to the latest mpi. + +\section{Building a Shared Library} +LibTomCrypt can also be built as a shared library (.so, .dll, etc...). With non-Windows platforms the assumption +of the presence of gcc and ``libtool'' has been made. These are fairly common on Unix/Linux/BSD platforms. To +build a .so shared library issue + +\begin{alltt} +make -f makefile.shared +\end{alltt} +This will use libtool and gcc to build a shared library ``libtomcrypt.la'' as well as a static library ``libtomcrypt.a'' +and install them into /usr/lib (and the headers into /usr/include). To link your application you should use the +libtool program in ``--mode=link''. + +You can also build LibTomCrypt as a shared library (DLL) in Windows with Cygwin. Issue the following + +\begin{alltt} +make -f makefile.cygwin_dll +\end{alltt} +This will build ``libtomcrypt.dll.a'' which is an import library for ``libtomcrypt.dll''. You must copy +``libtomcrypt.dll.a'' to your library directory, ``libtomcrypt.dll' to somewhere in your PATH and the header +files to your include directory. So long as ``libtomcrypt.dll'' is in your system path you can run any LibTomCrypt +program that uses it. \section{mycrypt\_cfg.h} -The file ``mycrypt\_cfg.h'' is what lets you control what functionality you want to remove from the library. By default, -everything the library has to offer it built. +The file ``mycrypt\_cfg.h'' is what lets you control various high level macros which control the behaviour +of the library. \subsubsection{ARGTYPE} This lets you control how the \_ARGCHK macro will behave. The macro is used to check pointers inside the functions against @@ -3226,17 +3393,18 @@ and no error checking will be performed. There are five macros related to endianess issues. For little endian platforms define, ENDIAN\_LITTLE. For big endian platforms define ENDIAN\_BIG. Similarly when the default word size of an ``unsigned long'' is 32-bits define ENDIAN\_32BITWORD or define ENDIAN\_64BITWORD when its 64-bits. If you do not define any of them the library will automatically use ENDIAN\_NEUTRAL -which will work on all platforms. Currently the system will automatically detect GCC or MSVC on a windows platform as well -as GCC on a PS2 platform. +which will work on all platforms. + +Currently LibTomCrypt will detect x86-32 and x86-64 running GCC as well as x86-32 running MSVC. \section{The Configure Script} -There are also options you can specify from the configure script or ``mycrypt\_config.h''. +There are also options you can specify from the configure script or ``mycrypt\_custom.h''. \subsubsection{X memory routines} -The makefiles must define three macros denoted as XMALLOC, XCALLOC and XFREE which resolve to the name of the respective -functions. This lets you substitute in your own memory routines. If you substitute in your own functions they must behave -like the standard C library functions in terms of what they expect as input and output. By default the library uses the -standard C routines. +At the top of mycrypt\_custom.h are four macros denoted as XMALLOC, XCALLOC, XREALLOC and XFREE which resolve to +the name of the respective functions. This lets you substitute in your own memory routines. If you substitute in +your own functions they must behave like the standard C library functions in terms of what they expect as input and +output. By default the library uses the standard C routines. \subsubsection{X clock routines} The rng\_get\_bytes() function can call a function that requires the clock() function. These macros let you override @@ -3244,17 +3412,22 @@ the default clock() used with a replacement. By default the standard C library \subsubsection{NO\_FILE} During the build if NO\_FILE is defined then any function in the library that uses file I/O will not call the file I/O -functions and instead simply return CRYPT\_ERROR. This should help resolve any linker errors stemming from a lack of +functions and instead simply return CRYPT\_NOP. This should help resolve any linker errors stemming from a lack of file I/O on embedded platforms. \subsubsection{CLEAN\_STACK} -When this functions is defined the functions that store key material on the stack will clean up afterwards. Assumes that -you have no memory paging with the stack. +When this functions is defined the functions that store key material on the stack will clean up afterwards. +Assumes that you have no memory paging with the stack. + +\subsubsection{LTC\_TEST} +When this has been defined the various self--test functions (for ciphers, hashes, prngs, etc) are included in the build. +When this has been undefined the tests are removed and if called will return CRYPT\_NOP. \subsubsection{Symmetric Ciphers, One-way Hashes, PRNGS and Public Key Functions} -There are a plethora of macros for the ciphers, hashes, PRNGs and public key functions which are fairly self-explanatory. -When they are defined the functionality is included otherwise it is not. There are some dependency issues which are -noted in the file. For instance, Yarrow requires CTR chaining mode, a block cipher and a hash function. +There are a plethora of macros for the ciphers, hashes, PRNGs and public key functions which are fairly +self-explanatory. When they are defined the functionality is included otherwise it is not. There are some +dependency issues which are noted in the file. For instance, Yarrow requires CTR chaining mode, a block +cipher and a hash function. \subsubsection{TWOFISH\_SMALL and TWOFISH\_TABLES} Twofish is a 128-bit symmetric block cipher that is provided within the library. The cipher itself is flexible enough @@ -3272,6 +3445,20 @@ it will not speed up the encryption or decryption functions. When this is defined some of the code such as the Rijndael and SAFER+ ciphers are replaced with smaller code variants. These variants are slower but can save quite a bit of code space. +\section{MPI Tweaks} +\subsection{RSA Only Tweak} +If you plan on only using RSA with moduli in the range of 1024 to 2560 bits you can enable a series of tweaks +to reduce the library size. Follow these steps + +\begin{enumerate} + \item Undefine MDSA, MECC and MDH from mycrypt\_custom.h + \item Undefine LTM\_ALL from tommath\_superclass.h + \item Define SC\_RSA\_1 from tommath\_superclass.h + \item Rebuild the library. +\end{enumerate} + + + \input{crypt.ind} \end{document} diff --git a/cscope.tmplst b/cscope.tmplst new file mode 100644 index 0000000..7fabc86 --- /dev/null +++ b/cscope.tmplst @@ -0,0 +1,219 @@ +./aes.c +./aes_tab.c +./base64_decode.c +./base64_encode.c +./blowfish.c +./burn_stack.c +./cast5.c +./cbc_decrypt.c +./cbc_encrypt.c +./cbc_getiv.c +./cbc_setiv.c +./cbc_start.c +./cfb_decrypt.c +./cfb_encrypt.c +./cfb_getiv.c +./cfb_setiv.c +./cfb_start.c +./chc.c +./crypt.c +./crypt_argchk.c +./crypt_cipher_descriptor.c +./crypt_cipher_is_valid.c +./crypt_find_cipher.c +./crypt_find_cipher_any.c +./crypt_find_cipher_id.c +./crypt_find_hash.c +./crypt_find_hash_any.c +./crypt_find_hash_id.c +./crypt_find_prng.c +./crypt_hash_descriptor.c +./crypt_hash_is_valid.c +./crypt_prng_descriptor.c +./crypt_prng_is_valid.c +./crypt_register_cipher.c +./crypt_register_hash.c +./crypt_register_prng.c +./crypt_unregister_cipher.c +./crypt_unregister_hash.c +./crypt_unregister_prng.c +./ctr_decrypt.c +./ctr_encrypt.c +./ctr_getiv.c +./ctr_setiv.c +./ctr_start.c +./demos/encrypt.c +./demos/hashsum.c +./demos/small.c +./demos/test/base64_test.c +./demos/test/cipher_hash_test.c +./demos/test/der_tests.c +./demos/test/dh_tests.c +./demos/test/dsa_test.c +./demos/test/ecc_test.c +./demos/test/mac_test.c +./demos/test/makefile +./demos/test/makefile.icc +./demos/test/makefile.msvc +./demos/test/makefile.shared +./demos/test/modes_test.c +./demos/test/pkcs_1_test.c +./demos/test/rsa_test.c +./demos/test/store_test.c +./demos/test/test.c +./demos/test/test.h +./demos/tv_gen.c +./demos/x86_prof.c +./der_decode_integer.c +./der_encode_integer.c +./der_get_multi_integer.c +./der_length_integer.c +./der_put_multi_integer.c +./des.c +./dh.c +./dh_sys.c +./dsa_export.c +./dsa_free.c +./dsa_import.c +./dsa_make_key.c +./dsa_sign_hash.c +./dsa_verify_hash.c +./dsa_verify_key.c +./eax_addheader.c +./eax_decrypt.c +./eax_decrypt_verify_memory.c +./eax_done.c +./eax_encrypt.c +./eax_encrypt_authenticate_memory.c +./eax_init.c +./eax_test.c +./ecb_decrypt.c +./ecb_encrypt.c +./ecb_start.c +./ecc.c +./ecc_sys.c +./error_to_string.c +./fortuna.c +./hash_file.c +./hash_filehandle.c +./hash_memory.c +./hmac_done.c +./hmac_file.c +./hmac_init.c +./hmac_memory.c +./hmac_process.c +./hmac_test.c +./is_prime.c +./ltc_tommath.h +./makefile +./makefile.cygwin_dll +./makefile.icc +./makefile.msvc +./makefile.shared +./md2.c +./md4.c +./md5.c +./mpi.c +./mpi_to_ltc_error.c +./mycrypt.h +./mycrypt_argchk.h +./mycrypt_cfg.h +./mycrypt_cipher.h +./mycrypt_custom.h +./mycrypt_hash.h +./mycrypt_macros.h +./mycrypt_misc.h +./mycrypt_pk.h +./mycrypt_pkcs.h +./mycrypt_prng.h +./noekeon.c +./notes/etc/whirlgen.c +./notes/etc/whirltest.c +./ocb_decrypt.c +./ocb_decrypt_verify_memory.c +./ocb_done_decrypt.c +./ocb_done_encrypt.c +./ocb_encrypt.c +./ocb_encrypt_authenticate_memory.c +./ocb_init.c +./ocb_ntz.c +./ocb_shift_xor.c +./ocb_test.c +./ofb_decrypt.c +./ofb_encrypt.c +./ofb_getiv.c +./ofb_setiv.c +./ofb_start.c +./omac_done.c +./omac_file.c +./omac_init.c +./omac_memory.c +./omac_process.c +./omac_test.c +./packet_store_header.c +./packet_valid_header.c +./pkcs_1_i2osp.c +./pkcs_1_mgf1.c +./pkcs_1_oaep_decode.c +./pkcs_1_oaep_encode.c +./pkcs_1_os2ip.c +./pkcs_1_pss_decode.c +./pkcs_1_pss_encode.c +./pkcs_1_v15_es_decode.c +./pkcs_1_v15_es_encode.c +./pkcs_1_v15_sa_decode.c +./pkcs_1_v15_sa_encode.c +./pkcs_5_1.c +./pkcs_5_2.c +./pmac_done.c +./pmac_file.c +./pmac_init.c +./pmac_memory.c +./pmac_ntz.c +./pmac_process.c +./pmac_shift_xor.c +./pmac_test.c +./rand_prime.c +./rc2.c +./rc4.c +./rc5.c +./rc6.c +./rmd128.c +./rmd160.c +./rng_get_bytes.c +./rng_make_prng.c +./rsa_decrypt_key.c +./rsa_encrypt_key.c +./rsa_export.c +./rsa_exptmod.c +./rsa_free.c +./rsa_import.c +./rsa_make_key.c +./rsa_sign_hash.c +./rsa_v15_decrypt_key.c +./rsa_v15_encrypt_key.c +./rsa_v15_sign_hash.c +./rsa_v15_verify_hash.c +./rsa_verify_hash.c +./s_ocb_done.c +./safer.c +./safer_tab.c +./saferp.c +./sha1.c +./sha224.c +./sha256.c +./sha384.c +./sha512.c +./skipjack.c +./sober128.c +./sober128tab.c +./sprng.c +./tiger.c +./tim_exptmod.c +./twofish.c +./twofish_tab.c +./whirl.c +./whirltab.c +./xtea.c +./yarrow.c +./zeromem.c diff --git a/demos/hashsum.c b/demos/hashsum.c index e0269b3..c633ca8 100644 --- a/demos/hashsum.c +++ b/demos/hashsum.c @@ -7,7 +7,7 @@ * more functions ;) */ -#include +#include int errno; @@ -26,7 +26,7 @@ int main(int argc, char **argv) printf("usage: ./hash algorithm file [file ...]\n"); printf("Algorithms:\n"); for (x = 0; hash_descriptor[x].name != NULL; x++) { - printf(" %s\n", hash_descriptor[x].name); + printf(" %s (%d)\n", hash_descriptor[x].name, hash_descriptor[x].ID); } exit(EXIT_SUCCESS); } @@ -66,6 +66,8 @@ int main(int argc, char **argv) void register_algs(void) { + int err; + #ifdef TIGER register_hash (&tiger_desc); #endif @@ -102,5 +104,12 @@ void register_algs(void) #ifdef WHIRLPOOL register_hash (&whirlpool_desc); #endif +#ifdef CHC_HASH + register_hash(&chc_desc); + if ((err = chc_register(register_cipher(&aes_enc_desc))) != CRYPT_OK) { + printf("chc_register error: %s\n", error_to_string(err)); + exit(EXIT_FAILURE); + } +#endif } diff --git a/demos/test/cipher_hash_test.c b/demos/test/cipher_hash_test.c index 046454b..2737623 100644 --- a/demos/test/cipher_hash_test.c +++ b/demos/test/cipher_hash_test.c @@ -23,12 +23,12 @@ int cipher_hash_test(void) for (x = 0; prng_descriptor[x].name != NULL; x++) { DO(prng_descriptor[x].test()); DO(prng_descriptor[x].start(&nprng)); - DO(prng_descriptor[x].add_entropy("helloworld12", 12, &nprng)); + DO(prng_descriptor[x].add_entropy((unsigned char *)"helloworld12", 12, &nprng)); DO(prng_descriptor[x].ready(&nprng)); n = sizeof(buf); - DO(prng_descriptor[x].export(buf, &n, &nprng)); + DO(prng_descriptor[x].pexport(buf, &n, &nprng)); prng_descriptor[x].done(&nprng); - DO(prng_descriptor[x].import(buf, n, &nprng)); + DO(prng_descriptor[x].pimport(buf, n, &nprng)); DO(prng_descriptor[x].ready(&nprng)); if (prng_descriptor[x].read(buf, 100, &nprng) != 100) { fprintf(stderr, "Error reading from imported PRNG!\n"); diff --git a/demos/test/der_tests.c b/demos/test/der_tests.c new file mode 100644 index 0000000..0c0e3df --- /dev/null +++ b/demos/test/der_tests.c @@ -0,0 +1,82 @@ +#include "test.h" + +int der_tests(void) +{ + unsigned long x, y, z, zz; + unsigned char buf[2][4096]; + mp_int a, b, c, d, e, f, g; + + DO(mpi_to_ltc_error(mp_init_multi(&a, &b, &c, &d, &e, &f, &g, NULL))); + for (zz = 0; zz < 16; zz++) { + for (z = 0; z < 1024; z++) { + if (yarrow_read(buf[0], z, &test_yarrow) != z) { + printf("Failed to read %lu bytes from yarrow\n", z); + return 1; + } + DO(mpi_to_ltc_error(mp_read_unsigned_bin(&a, buf[0], z))); + x = sizeof(buf[0]); + DO(der_encode_integer(&a, buf[0], &x)); + y = x; + mp_zero(&b); + DO(der_decode_integer(buf[0], &y, &b)); + if (y != x || mp_cmp(&a, &b) != MP_EQ) { + printf("%lu: %lu vs %lu\n", z, x, y); +#ifdef BN_MP_TORADIX_C + mp_todecimal(&a, buf[0]); + mp_todecimal(&b, buf[1]); + printf("a == %s\nb == %s\n", buf[0], buf[1]); +#endif + mp_clear_multi(&a, &b, &c, &d, &e, &f, &g, NULL); + return 1; + } + } + } + + +/* test the multi */ + mp_set(&a, 1); + x = sizeof(buf[0]); + DO(der_put_multi_integer(buf[0], &x, &a, NULL)); + y = x; + mp_zero(&a); + DO(der_get_multi_integer(buf[0], &y, &a, NULL)); + if (x != y || mp_cmp_d(&a, 1)) { + printf("%lu, %lu, %d\n", x, y, mp_cmp_d(&a, 1)); + mp_clear_multi(&a, &b, &c, &d, &e, &f, &g, NULL); + return 1; + } + + mp_set(&a, 1); + mp_set(&b, 2); + x = sizeof(buf[0]); + DO(der_put_multi_integer(buf[0], &x, &a, &b, NULL)); + y = x; + mp_zero(&a); + mp_zero(&b); + DO(der_get_multi_integer(buf[0], &y, &a, &b, NULL)); + if (x != y || mp_cmp_d(&a, 1) || mp_cmp_d(&b, 2)) { + printf("%lu, %lu, %d, %d\n", x, y, mp_cmp_d(&a, 1), mp_cmp_d(&b, 2)); + mp_clear_multi(&a, &b, &c, &d, &e, &f, &g, NULL); + return 1; + } + + mp_set(&a, 1); + mp_set(&b, 2); + mp_set(&c, 3); + x = sizeof(buf[0]); + DO(der_put_multi_integer(buf[0], &x, &a, &b, &c, NULL)); + y = x; + mp_zero(&a); + mp_zero(&b); + mp_zero(&c); + DO(der_get_multi_integer(buf[0], &y, &a, &b, &c, NULL)); + if (x != y || mp_cmp_d(&a, 1) || mp_cmp_d(&b, 2) || mp_cmp_d(&c, 3)) { + printf("%lu, %lu, %d, %d, %d\n", x, y, mp_cmp_d(&a, 1), mp_cmp_d(&b, 2), mp_cmp_d(&c, 3)); + mp_clear_multi(&a, &b, &c, &d, &e, &f, &g, NULL); + return 1; + } + + + mp_clear_multi(&a, &b, &c, &d, &e, &f, &g, NULL); + return 0; +} diff --git a/demos/test/dh_tests.c b/demos/test/dh_tests.c index 785a97b..6977c58 100644 --- a/demos/test/dh_tests.c +++ b/demos/test/dh_tests.c @@ -1,5 +1,7 @@ #include "test.h" +#ifdef MDH + int dh_tests (void) { unsigned char buf[3][4096]; @@ -85,3 +87,13 @@ int dh_tests (void) dh_free (&usera); return 0; } + +#else + +int dh_tests(void) +{ + printf("NOP"); + return 0; +} + +#endif diff --git a/demos/test/dsa_test.c b/demos/test/dsa_test.c index 2076089..c5eeb6d 100644 --- a/demos/test/dsa_test.c +++ b/demos/test/dsa_test.c @@ -1,10 +1,12 @@ #include "test.h" +#ifdef MDSA + int dsa_test(void) { unsigned char msg[16], out[1024], out2[1024]; - unsigned long x, y; - int err, stat1, stat2; + unsigned long x; + int stat1, stat2; dsa_key key, key2; /* make a random key */ @@ -49,3 +51,13 @@ int dsa_test(void) return 0; } + +#else + +int dsa_test(void) +{ + printf("NOP"); + return 0; +} + +#endif diff --git a/demos/test/ecc_test.c b/demos/test/ecc_test.c index b64cbcf..eb66c58 100644 --- a/demos/test/ecc_test.c +++ b/demos/test/ecc_test.c @@ -1,5 +1,7 @@ #include "test.h" +#ifdef MECC + int ecc_tests (void) { unsigned char buf[4][4096]; @@ -87,3 +89,13 @@ int ecc_tests (void) ecc_free (&usera); return 0; } + +#else + +int ecc_tests(void) +{ + printf("NOP"); + return 0; +} + +#endif diff --git a/demos/test/makefile b/demos/test/makefile index 5eb0690..e306d17 100644 --- a/demos/test/makefile +++ b/demos/test/makefile @@ -10,7 +10,7 @@ CFLAGS += -fomit-frame-pointer default: test OBJECTS=test.o cipher_hash_test.o mac_test.o modes_test.o \ -pkcs_1_test.o store_test.o rsa_test.o ecc_test.o dsa_test.c dh_tests.o +pkcs_1_test.o store_test.o rsa_test.o ecc_test.o dsa_test.o dh_tests.o der_tests.o #uncomment this to get heap checking [e.g. memory leaks]. Note #that you *MUST* build libtomcrypt.a with -g3 enabled [and make install it] @@ -19,7 +19,7 @@ pkcs_1_test.o store_test.o rsa_test.o ecc_test.o dsa_test.c dh_tests.o #CCMALLOC = -lccmalloc -ldl test: $(OBJECTS) - $(CC) $(OBJECTS) -ltomcrypt $(CCMALLOC) -o test + $(CC) $(OBJECTS) /usr/lib/libtomcrypt.a $(CCMALLOC) -o test clean: - rm -f test *.o *.obj *.exe *~ + rm -rf test *.o *.obj *.exe *~ .libs diff --git a/demos/test/makefile.icc b/demos/test/makefile.icc index 22c7154..b32c9ba 100644 --- a/demos/test/makefile.icc +++ b/demos/test/makefile.icc @@ -5,7 +5,7 @@ CC=icc default: test OBJECTS=test.o cipher_hash_test.o mac_test.o modes_test.o \ -pkcs_1_test.o store_test.o rsa_test.o ecc_test.o dsa_test.c dh_tests.o +pkcs_1_test.o store_test.o rsa_test.o ecc_test.o dsa_test.o dh_tests.o der_tests.o test: $(OBJECTS) $(CC) $(OBJECTS) -ltomcrypt -o test diff --git a/demos/test/makefile.msvc b/demos/test/makefile.msvc index c1ca8e0..8769ecf 100644 --- a/demos/test/makefile.msvc +++ b/demos/test/makefile.msvc @@ -4,7 +4,7 @@ CFLAGS = $(CFLAGS) /W3 /Ox -I../../ -I./ default: test.exe OBJECTS = test.obj cipher_hash_test.obj mac_test.obj modes_test.obj \ -pkcs_1_test.obj store_test.obj rsa_test.obj ecc_test.obj dsa_test.c dh_tests.obj +pkcs_1_test.obj store_test.obj rsa_test.obj ecc_test.obj dsa_test.c dh_tests.obj der_tests.obj test.exe: $(OBJECTS) diff --git a/demos/test/makefile.shared b/demos/test/makefile.shared new file mode 100644 index 0000000..d90c1da --- /dev/null +++ b/demos/test/makefile.shared @@ -0,0 +1,19 @@ +# make test harness, it is good. +CFLAGS += -Wall -W -Os -I../../ -I./ + +# if you're not debugging +CFLAGS += -fomit-frame-pointer + +default: test + +#if you don't have mpi.o +#MPISHARED=-ltommath + +OBJECTS=test.o cipher_hash_test.o mac_test.o modes_test.o \ +pkcs_1_test.o store_test.o rsa_test.o ecc_test.o dsa_test.o dh_tests.o der_tests.o + +test: $(OBJECTS) + libtool --mode=link gcc $(CFLAGS) $(OBJECTS) -o test -ltomcrypt $(MPISHARED) + +clean: + rm -f test *.o *.obj *.exe *~ diff --git a/demos/test/pkcs_1_test.c b/demos/test/pkcs_1_test.c index ef7c81d..52af7b6 100644 --- a/demos/test/pkcs_1_test.c +++ b/demos/test/pkcs_1_test.c @@ -1,5 +1,7 @@ #include "test.h" +#ifdef PKCS_1 + int pkcs_1_test(void) { unsigned char buf[3][128]; @@ -101,3 +103,14 @@ int pkcs_1_test(void) } return 0; } + +#else + +int pkcs_1_test(void) +{ + printf("NOP"); + return 0; +} + +#endif + diff --git a/demos/test/rsa_test.c b/demos/test/rsa_test.c index 777fc87..a6034dd 100644 --- a/demos/test/rsa_test.c +++ b/demos/test/rsa_test.c @@ -1,12 +1,13 @@ #include "test.h" -#define RSA_MSGSIZE 78 +#ifdef MRSA +#define RSA_MSGSIZE 78 int rsa_test(void) { unsigned char in[1024], out[1024], tmp[1024]; - rsa_key key; + rsa_key key, privKey, pubKey; int hash_idx, prng_idx, stat, stat2; unsigned long rsa_msgsize, len, len2; static unsigned char lparam[] = { 0x01, 0x02, 0x03, 0x04 }; @@ -128,30 +129,90 @@ int rsa_test(void) /* sign a message (unsalted, lower cholestorol and Atkins approved) now */ len = sizeof(out); DO(rsa_sign_hash(in, 20, out, &len, &test_yarrow, prng_idx, hash_idx, 0, &key)); + +/* export key and import as both private and public */ + len2 = sizeof(tmp); + DO(rsa_export(tmp, &len2, PK_PRIVATE, &key)); + DO(rsa_import(tmp, len2, &privKey)); + len2 = sizeof(tmp); + DO(rsa_export(tmp, &len2, PK_PUBLIC, &key)); + DO(rsa_import(tmp, len2, &pubKey)); + + /* verify with original */ DO(rsa_verify_hash(out, len, in, 20, &test_yarrow, prng_idx, hash_idx, 0, &stat, &key)); /* change a byte */ in[0] ^= 1; DO(rsa_verify_hash(out, len, in, 20, &test_yarrow, prng_idx, hash_idx, 0, &stat2, &key)); if (!(stat == 1 && stat2 == 0)) { - printf("rsa_verify_hash (unsalted) failed, %d, %d", stat, stat2); + printf("rsa_verify_hash (unsalted, origKey) failed, %d, %d", stat, stat2); + rsa_free(&key); + rsa_free(&pubKey); + rsa_free(&privKey); return 1; } - /* sign a message (salted) now */ - len = sizeof(out); - DO(rsa_sign_hash(in, 20, out, &len, &test_yarrow, prng_idx, hash_idx, 8, &key)); - DO(rsa_verify_hash(out, len, in, 20, &test_yarrow, prng_idx, hash_idx, 8, &stat, &key)); + /* verify with privKey */ /* change a byte */ in[0] ^= 1; - DO(rsa_verify_hash(out, len, in, 20, &test_yarrow, prng_idx, hash_idx, 8, &stat2, &key)); + DO(rsa_verify_hash(out, len, in, 20, &test_yarrow, prng_idx, hash_idx, 0, &stat, &privKey)); + /* change a byte */ + in[0] ^= 1; + DO(rsa_verify_hash(out, len, in, 20, &test_yarrow, prng_idx, hash_idx, 0, &stat2, &privKey)); + + if (!(stat == 1 && stat2 == 0)) { + printf("rsa_verify_hash (unsalted, privKey) failed, %d, %d", stat, stat2); + rsa_free(&key); + rsa_free(&pubKey); + rsa_free(&privKey); + return 1; + } + + /* verify with pubKey */ + /* change a byte */ + in[0] ^= 1; + DO(rsa_verify_hash(out, len, in, 20, &test_yarrow, prng_idx, hash_idx, 0, &stat, &pubKey)); + /* change a byte */ + in[0] ^= 1; + DO(rsa_verify_hash(out, len, in, 20, &test_yarrow, prng_idx, hash_idx, 0, &stat2, &pubKey)); + + if (!(stat == 1 && stat2 == 0)) { + printf("rsa_verify_hash (unsalted, pubkey) failed, %d, %d", stat, stat2); + rsa_free(&key); + rsa_free(&pubKey); + rsa_free(&privKey); + return 1; + } + + /* sign a message (salted) now (use privKey to make, pubKey to verify) */ + len = sizeof(out); + DO(rsa_sign_hash(in, 20, out, &len, &test_yarrow, prng_idx, hash_idx, 8, &privKey)); + DO(rsa_verify_hash(out, len, in, 20, &test_yarrow, prng_idx, hash_idx, 8, &stat, &pubKey)); + /* change a byte */ + in[0] ^= 1; + DO(rsa_verify_hash(out, len, in, 20, &test_yarrow, prng_idx, hash_idx, 8, &stat2, &pubKey)); if (!(stat == 1 && stat2 == 0)) { printf("rsa_verify_hash (salted) failed, %d, %d", stat, stat2); + rsa_free(&key); + rsa_free(&pubKey); + rsa_free(&privKey); return 1; } /* free the key and return */ rsa_free(&key); + rsa_free(&pubKey); + rsa_free(&privKey); return 0; } + +#else + +int rsa_test(void) +{ + printf("NOP"); + return 0; +} + +#endif diff --git a/demos/test/test.c b/demos/test/test.c index b516804..a56e5d6 100644 --- a/demos/test/test.c +++ b/demos/test/test.c @@ -9,12 +9,13 @@ test_entry test_list[26] = { {"cipher_hash_test", "b", "a", cipher_hash_test }, {"modes_test", "c", "b", modes_test }, {"mac_test", "d", "c", mac_test }, +{"der_test", "e", "", der_tests }, -{"pkcs_1_test", "e", "b", pkcs_1_test }, -{"rsa_test", "f", "", rsa_test }, -{"ecc_test", "g", "a", ecc_tests }, -{"dsa_test", "h", "a", dsa_test }, -{"dh_test", "i", "a", dh_tests }, +{"pkcs_1_test", "f", "e", pkcs_1_test }, +{"rsa_test", "g", "e", rsa_test }, +{"ecc_test", "h", "a", ecc_tests }, +{"dsa_test", "i", "a", dsa_test }, +{"dh_test", "j", "a", dh_tests }, {NULL, NULL, NULL, NULL} }; @@ -32,6 +33,8 @@ void run_cmd(int res, int line, char *file, char *cmd) void register_algs(void) { + int err; + #ifdef RIJNDAEL register_cipher (&aes_desc); #endif @@ -111,6 +114,14 @@ void register_algs(void) #ifdef WHIRLPOOL register_hash (&whirlpool_desc); #endif +#ifdef CHC_HASH + register_hash(&chc_desc); + if ((err = chc_register(register_cipher(&aes_enc_desc))) != CRYPT_OK) { + printf("chc_register error: %s\n", error_to_string(err)); + exit(EXIT_FAILURE); + } +#endif + #ifdef YARROW register_prng(&yarrow_desc); @@ -197,6 +208,7 @@ void stack_check(void) int main(void) { int x; + unsigned char buf[16]; /* setup stack checker */ srand(time(NULL)); @@ -212,23 +224,32 @@ int main(void) // start dummy yarrow for internal use DO(yarrow_start(&test_yarrow)); - DO(yarrow_add_entropy("test", 4, &test_yarrow)); + sprng_read(buf, 16, NULL); + DO(yarrow_add_entropy(buf, 16, &test_yarrow)); DO(yarrow_ready(&test_yarrow)); // output sizes printf("Sizes of objects (in bytes)\n"); - printf("\tsymmetric_key\t=\t%5d\n", sizeof(symmetric_key)); - printf("\thash_state\t=\t%5d\n", sizeof(hash_state)); - printf("\thmac_state\t=\t%5d\n", sizeof(hmac_state)); - printf("\tomac_state\t=\t%5d\n", sizeof(omac_state)); - printf("\tpmac_state\t=\t%5d\n", sizeof(pmac_state)); - printf("\tocb_state\t=\t%5d\n", sizeof(ocb_state)); - printf("\teax_state\t=\t%5d\n", sizeof(eax_state)); - printf("\tmp_int\t\t=\t%5d\n", sizeof(mp_int)); - printf("\trsa_key\t\t=\t%5d\n", sizeof(rsa_key)); - printf("\tdsa_key\t\t=\t%5d\n", sizeof(dsa_key)); - printf("\tdh_key\t\t=\t%5d\n", sizeof(dh_key)); - printf("\tecc_key\t\t=\t%5d\n", sizeof(ecc_key)); + printf("\tsymmetric_key\t=\t%5lu\n", sizeof(symmetric_key)); + printf("\thash_state\t=\t%5lu\n", sizeof(hash_state)); + printf("\thmac_state\t=\t%5lu\n", sizeof(hmac_state)); + printf("\tomac_state\t=\t%5lu\n", sizeof(omac_state)); + printf("\tpmac_state\t=\t%5lu\n", sizeof(pmac_state)); + printf("\tocb_state\t=\t%5lu\n", sizeof(ocb_state)); + printf("\teax_state\t=\t%5lu\n", sizeof(eax_state)); + printf("\tmp_int\t\t=\t%5lu\n", sizeof(mp_int)); +#ifdef MRSA + printf("\trsa_key\t\t=\t%5lu\n", sizeof(rsa_key)); +#endif +#ifdef MDSA + printf("\tdsa_key\t\t=\t%5lu\n", sizeof(dsa_key)); +#endif +#ifdef MDH + printf("\tdh_key\t\t=\t%5lu\n", sizeof(dh_key)); +#endif +#ifdef MECC + printf("\tecc_key\t\t=\t%5lu\n", sizeof(ecc_key)); +#endif printf("\n\n"); // do tests diff --git a/demos/test/test.h b/demos/test/test.h index 44cdf92..1dee4bf 100644 --- a/demos/test/test.h +++ b/demos/test/test.h @@ -35,5 +35,6 @@ int rsa_test(void); int ecc_tests(void); int dsa_test(void); int dh_tests(void); +int der_tests(void); #endif diff --git a/demos/tv_gen.c b/demos/tv_gen.c index 101976e..07633fc 100644 --- a/demos/tv_gen.c +++ b/demos/tv_gen.c @@ -2,6 +2,8 @@ void reg_algs(void) { + int err; + #ifdef RIJNDAEL register_cipher (&aes_desc); #endif @@ -82,6 +84,14 @@ void reg_algs(void) #ifdef WHIRLPOOL register_hash (&whirlpool_desc); #endif +#ifdef CHC_HASH + register_hash(&chc_desc); + if ((err = chc_register(register_cipher(&aes_desc))) != CRYPT_OK) { + printf("chc_register error: %s\n", error_to_string(err)); + exit(EXIT_FAILURE); + } +#endif + } void hash_gen(void) @@ -98,7 +108,7 @@ void hash_gen(void) fprintf(out, "Hash Test Vectors:\n\nThese are the hashes of nn bytes '00 01 02 03 .. (nn-1)'\n\n"); for (x = 0; hash_descriptor[x].name != NULL; x++) { - buf = XMALLOC(2 * hash_descriptor[x].blocksize); + buf = XMALLOC(2 * hash_descriptor[x].blocksize + 1); if (buf == NULL) { perror("can't alloc mem"); exit(EXIT_FAILURE); @@ -222,7 +232,7 @@ void hmac_gen(void) key[y] = (y&255); } - input = XMALLOC(hash_descriptor[x].blocksize * 2); + input = XMALLOC(hash_descriptor[x].blocksize * 2 + 1); if (input == NULL) { perror("Can't malloc memory"); exit(EXIT_FAILURE); diff --git a/demos/tv_gen.lo b/demos/tv_gen.lo new file mode 100644 index 0000000..23b3e7c --- /dev/null +++ b/demos/tv_gen.lo @@ -0,0 +1,12 @@ +# demos/tv_gen.lo - a libtool object file +# Generated by ltmain.sh - GNU libtool 1.5.2 (1.1220.2.60 2004/01/25 12:25:08) +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# Name of the PIC object. +pic_object='.libs/tv_gen.o' + +# Name of the non-PIC object. +non_pic_object='tv_gen.o' + diff --git a/demos/x86_prof.c b/demos/x86_prof.c index 7293bd6..b77b76c 100644 --- a/demos/x86_prof.c +++ b/demos/x86_prof.c @@ -49,9 +49,9 @@ void tally_results(int type) static ulong64 rdtsc (void) { #if defined __GNUC__ - #ifdef __i386__ - ulong64 a; - __asm__ __volatile__ ("rdtsc ":"=A" (a)); + #if defined(__i386__) || defined(__x86_64__) + unsigned long long a; + __asm__ __volatile__ ("rdtsc\nmovl %%eax,%0\nmovl %%edx,4+%0\n"::"m"(a):"%eax","%edx"); return a; #else /* gcc-IA64 version */ unsigned long result; @@ -110,6 +110,7 @@ void init_timer(void) void reg_algs(void) { + int err; #ifdef RIJNDAEL register_cipher (&aes_desc); #endif @@ -190,6 +191,14 @@ void reg_algs(void) #ifdef WHIRLPOOL register_hash (&whirlpool_desc); #endif +#ifdef CHC_HASH + register_hash(&chc_desc); + if ((err = chc_register(register_cipher(&aes_desc))) != CRYPT_OK) { + printf("chc_register error: %s\n", error_to_string(err)); + exit(EXIT_FAILURE); + } +#endif + #ifndef YARROW #error This demo requires Yarrow. diff --git a/der_decode_integer.c b/der_decode_integer.c new file mode 100644 index 0000000..71ce1f6 --- /dev/null +++ b/der_decode_integer.c @@ -0,0 +1,83 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + */ + +#include "mycrypt.h" + + +/* decodes a DER INTEGER in [in]. You have to tell this function + * how many bytes are available [inlen]. It will then attempt to + * read the INTEGER. If all goes well it stores the number of bytes + * read in [inlen] and the number in [num]. + */ +int der_decode_integer(const unsigned char *in, unsigned long *inlen, mp_int *num) +{ + unsigned long tmplen, y, z; + + _ARGCHK(num != NULL); + _ARGCHK(in != NULL); + _ARGCHK(inlen != NULL); + + /* save copy of max output size */ + tmplen = *inlen; + *inlen = 0; + + /* min DER INTEGER is 0x02 01 00 == 0 */ + if (tmplen < (1 + 1 + 1)) { + return CRYPT_INVALID_PACKET; + } + + /* ok expect 0x02 when we AND with 0011 1111 [3F] */ + if ((*in++ & 0x3F) != 0x02) { + return CRYPT_INVALID_PACKET; + } + ++(*inlen); + + /* now decode the len stuff */ + z = *in++; + ++(*inlen); + + if ((z & 0x80) == 0x00) { + /* short form */ + + /* will it overflow? */ + if (*inlen + z > tmplen) { + return CRYPT_INVALID_PACKET; + } + + /* no so read it */ + (*inlen) += z; + return mpi_to_ltc_error(mp_read_unsigned_bin(num, (unsigned char *)in, z)); + } else { + /* long form */ + z &= 0x7F; + + /* will number of length bytes overflow? (or > 4) */ + if (((*inlen + z) > tmplen) || (z > 4)) { + return CRYPT_INVALID_PACKET; + } + + /* now read it in */ + y = 0; + while (z--) { + y = ((unsigned long)(*in++)) | (y << 8); + ++(*inlen); + } + + /* now will reading y bytes overrun? */ + if ((*inlen + y) > tmplen) { + return CRYPT_INVALID_PACKET; + } + + /* no so read it */ + (*inlen) += y; + return mpi_to_ltc_error(mp_read_unsigned_bin(num, (unsigned char *)in, y)); + } +} diff --git a/der_encode_integer.c b/der_encode_integer.c new file mode 100644 index 0000000..b742dec --- /dev/null +++ b/der_encode_integer.c @@ -0,0 +1,93 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + */ + +#include "mycrypt.h" + +/* Exports a positive bignum as DER format (upto 2^32 bytes in size) */ +int der_encode_integer(mp_int *num, unsigned char *out, unsigned long *outlen) +{ + unsigned long tmplen, x, y, z; + int err, leading_zero; + + _ARGCHK(num != NULL); + _ARGCHK(out != NULL); + _ARGCHK(outlen != NULL); + + /* find out how big this will be */ + if ((err = der_length_integer(num, &tmplen)) != CRYPT_OK) { + return err; + } + + if (*outlen < tmplen) { + return CRYPT_BUFFER_OVERFLOW; + } + + /* we only need a leading zero if the msb of the first byte is one */ + if ((mp_count_bits(num) & 7) == 7 || mp_iszero(num) == MP_YES) { + leading_zero = 1; + } else { + leading_zero = 0; + } + + /* get length of num in bytes (plus 1 since we force the msbyte to zero) */ + y = mp_unsigned_bin_size(num) + leading_zero; + + /* now store initial data */ + *out++ = 0x02; + if (y < 128) { + /* short form */ + *out++ = (unsigned char)y; + } else { + /* long form (relies on y != 0) */ + + /* get length of length... ;-) */ + x = y; + z = 0; + while (x) { + ++z; + x >>= 8; + } + + /* store length of length */ + *out++ = 0x80 | ((unsigned char)z); + + /* now store length */ + + /* first shift length up so msbyte != 0 */ + x = y; + while ((x & 0xFF000000) == 0) { + x <<= 8; + } + + /* now store length */ + while (z--) { + *out++ = (unsigned char)((x >> 24) & 0xFF); + x <<= 8; + } + } + + /* now store msbyte of zero if num is non-zero */ + if (leading_zero) { + *out++ = 0x00; + } + + /* if it's not zero store it as big endian */ + if (mp_iszero(num) == MP_NO) { + /* now store the mpint */ + if ((err = mp_to_unsigned_bin(num, out)) != MP_OKAY) { + return mpi_to_ltc_error(err); + } + } + + /* we good */ + *outlen = tmplen; + return CRYPT_OK; +} diff --git a/der_get_multi_integer.c b/der_get_multi_integer.c new file mode 100644 index 0000000..d2b83c5 --- /dev/null +++ b/der_get_multi_integer.c @@ -0,0 +1,50 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + */ +#include +#include "mycrypt.h" + +/* will read multiple DER INTEGER encoded mp_ints from src + * of upto [inlen] bytes. It will store the number of bytes + * read back into [inlen]. + */ +int der_get_multi_integer(const unsigned char *src, unsigned long *inlen, + mp_int *num, ...) +{ + va_list args; + mp_int *next; + unsigned long wrote, len; + int err; + + _ARGCHK(src != NULL); + _ARGCHK(inlen != NULL); + + /* setup va list */ + next = num; + len = *inlen; + wrote = 0; + va_start(args, num); + + while (next != NULL) { + if ((err = der_decode_integer(src, inlen, next)) != CRYPT_OK) { + va_end(args); + return err; + } + wrote += *inlen; + src += *inlen; + len -= *inlen; + *inlen = len; + next = va_arg(args, mp_int*); + } + va_end(args); + *inlen = wrote; + return CRYPT_OK; +} + diff --git a/der_length_integer.c b/der_length_integer.c new file mode 100644 index 0000000..5291f82 --- /dev/null +++ b/der_length_integer.c @@ -0,0 +1,54 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + */ + +#include "mycrypt.h" + +/* Gets length of DER encoding of num */ + +int der_length_integer(mp_int *num, unsigned long *outlen) +{ + unsigned long z, len; + int leading_zero; + + _ARGCHK(num != NULL); + _ARGCHK(outlen != NULL); + + /* we only need a leading zero if the msb of the first byte is one */ + if ((mp_count_bits(num) & 7) == 7 || mp_iszero(num) == MP_YES) { + leading_zero = 1; + } else { + leading_zero = 0; + } + + /* size for bignum */ + z = len = leading_zero + mp_unsigned_bin_size(num); + + /* we need a 0x02 */ + ++len; + + /* now we need a length */ + if (z < 128) { + /* short form */ + ++len; + } else { + /* long form (relies on z != 0) */ + ++len; + + while (z) { + ++len; + z >>= 8; + } + } + + *outlen = len; + return CRYPT_OK; +} + diff --git a/der_put_multi_integer.c b/der_put_multi_integer.c new file mode 100644 index 0000000..e166e0b --- /dev/null +++ b/der_put_multi_integer.c @@ -0,0 +1,49 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + */ +#include +#include "mycrypt.h" + +/* store multiple mp_ints in DER INTEGER format to the dst, will not + * overflow the length you give it [outlen] and store the number of + * bytes used in [outlen] + */ +int der_put_multi_integer(unsigned char *dst, unsigned long *outlen, + mp_int *num, ...) +{ + va_list args; + mp_int *next; + unsigned long wrote, len; + int err; + + _ARGCHK(dst != NULL); + _ARGCHK(outlen != NULL); + + /* setup va list */ + next = num; + len = *outlen; + wrote = 0; + va_start(args, num); + + while (next != NULL) { + if ((err = der_encode_integer(next, dst, outlen)) != CRYPT_OK) { + va_end(args); + return err; + } + wrote += *outlen; + dst += *outlen; + len -= *outlen; + *outlen = len; + next = va_arg(args, mp_int*); + } + va_end(args); + *outlen = wrote; + return CRYPT_OK; +} diff --git a/doc/crypt.pdf b/doc/crypt.pdf index 778017af5d7619a0c8e9e03f305bf91b97d266f2..c0ad1e303abe38f74436110e325755fe871bffe1 100644 GIT binary patch delta 189277 zcmZU3Q*b5>uxxDWOR}+T+qRR9ZF`e^vF&VZ+qSi_ZQHv4sXF)N-kO)0s(GE6?w*eR z24pN^$4dbx6$Y75x;|*1wa6Nt-t82^M-gE`v0gZQQN;cp_XqTjZd0Tnr&^d>Sgi0% zk;NZPd2B`MSM4C;NzQ>YH|x5=BU2~6NfTgdgP##GxIxI^kU?umM1!i(YA{Z7Y!x}= zv#Yo=SI#R`bv!%0@+yXuB}<<0t3@*Lm>VRw-gg^(2;$f zV@YIT#XT+PT)XUmkkb-o(s*>biC;OFD^4%N;`h}OSU;S{zH+;rr{AZ%*em7 z9~Ye0r{_ZYgp! z0=1+JEeoC=@+Z8hCBnQ9Rk@fPvgAU4)PnP~^W%!YO%Zb%6VTk1-BbBQVT`Rnw~k0x z3rDUh6bdIja3dnFNhJLjD_`Q2f}JE9Z@i-^0?g;6g}q21DydONg)2z_)ln0wKK-cM z9(#cV@r?X~&|7oFb@eorxWvL9s!{lRal-G-31(PE;9t|`BpTE7`IsihUg#2Z-H?PQ zG7lMQu{I>ZPoSL>w{xvYQ8CgVH3h}WPOq;C0aOUTG?*kJS`{fAQf&jWl!VWILzT6V8Pq}Sa?B#nDyG1u{B!*(GAF0sx*FPUC&zi=)OZA0zOF&k zmc#=HD`rnL{!&!+3m?7JGGsz|%fdoKaB!y&`MaM3tiT8%6|tW1fAQfp!X^e&(#w+L zZZ1#>&&Ndw(gWVdMbz&Oc!-*0bO)Ek38q{fIr}u&nx{m3jU*9lN&R#{P4R3_4h%U7 zi+y}hE`Iuybt_rCuBg^d+M8ot{&~nYmjVkLhA*b)Uv{&L6PsNl~ zx(a4`a3Jos=&#=veXYY>x%7B;%&}$t-lZPrc|$FFQMI%Qau?TFpjF7skvz^nl5UJpwdc;`Gg+Zb7O${Fx5X+=5)>a5s!tinYtA zN-W37y5$Hhw=nmkyde$hxl$P@I?VD!L)zb!Z9rzIO<3tO)I3ca&UrKbugHxt%1WkC zY8-REoLPq`CoF4QG!m7qL_76uwKZ3rDf=w%`1S!%D*_5QPcOIZ7+5P%bEOJSEgOJG?v^pCObNzWHTLdo)FIgHUueI2nK7abWoT%My870~Br zJLcR1o$#h)p{pjcelScTePnrb+-`04HwvnT^8r_xRKc%TV{s^pi2g zOS7Q7vfD@s7D&%-aO2bo424OWLjj$kzz^_$$91aoO)m(ne=3H8;4<3`I~DPJ5<`n>89a)Hx6H*-V^Ca3N_SsdutL4y!!1VeE9mAB6N?7^@n zG+DVA5q?x@jg{gDS=0%$nV2{DT59lEm$cDZoR-pJ+xa>{34J75BMXI%*h8yip{lhH z!)-LjZfE7_r&=oCYE#W0q3dwu90>D#I%TNOxcYHAS`}VC`pY?zeJ(CFuRy=+JK+dP z=Op{~@-%@4wf9xzFCxFvyBy1Vq#$T>!Oytw@H39GT*+z2e}c6Q_Ch7>eighZAA!Ns z6QUTB+sZPJ3Gw^cNmKd$LLjK!b7`3q5?C{)*vj-sX}^G4xMMyhL-DHIkI<-Re_Ab3)|iCRbM$E zB9`xj5;C0*Mb%2ijeQyJ@4rNz;}gs5dop6KIDa7t#j_b<(ylRsT5z$f-!PzNtpLkW^S$!yxy_wQ4n3ykao6o6aLu&DmeulST7&+?1|t|t(8qCdxZL#%UL7rOh_@0{||IinFD);FEK_0Z%5u=NT&17dL}X!5xZPaZsDK_Dbpa{j0172O*&utE;( z<*R^3+Yq$O;)<#T0g95a7_p_Vt}0Qlscm9RWSgdGUN*GTXpKeYR^x(o z_nd`$H{c&HjAoCiqGF1VZ+qdQ;!X8Ys}=AqTL z7~_yioG4W@ao<5pwc0P6|K&L=;YxxndZM1sL1l9+9gP; z`kxF6WaB}!>J$K|{?*+enEcF8aG@RsKWtF@Ndv9mGfq&|sCU#mqLPEWc8HMLwSiiQ6xVM|y|F?sT3KP1~w;Y&n-O&{g`@Ucf_yHI~fsdw2K~^^C(Q_8#iLTqxnBf^w<6om`{aZ#@&K z+5+1(&XpWw&=`N(sNcHQ^VAJyO{@!BCs={4b!70lFOqXZAe3}f`CHB^VclXXHXs_##onbL%>gyVniFTtJIG5s)O(-s#57mH)a37<2+;aoVJ$ z0o$dOKTcg*v#g2$%oFa~a@;%9RXj?kUyd1Mfl0*`$L%D)i~F~xX$OBnfzcA8)&d)* z$#ScGyUat7@)WTdk}}4ZHGQEd4=N4yV)nF%==@p!p&)6+M+9vi=cF&k{`2@^$~0FE zDrx~E$v8zIHxj!~zn#B8(H$gfz#-t*ny&HaiTA<_T{E?4?xKi9-RI>+4tW|2tY=NX zP>YeG`4BNXORFohp+a+!GZ@z8qXT}o)2$b6v$CGaZya&?{S8Vn;vt~Q=72Z z&e=-T*WMUgcVuij@~1d)cDV+GM8>CMUv5uXptGvt;@(K>Tja`V!l58glD|>X`&~cW zz2|$zBn_zi6r9C!K`VJir^|MVsbE7CL~>%(V@P1o0+?X^&7jOXGGCMMzkrBbX#1{x z)-h7^F*?p$_5qq(W#RS!{my0yvWJM~?SIm|!y?8Xnx=q=?=nY-RRe`cvm+35Z)z%G zMQ@4?myToZ?7?v{vnzzkSjLXuZOw(&GQn|~XkqiqN!f3s5xQCZH$GiOp?O4L7$ ztB@4`;RGeUf9Jy?Q6M^!-~j7Q`r9Y)xL_P{1ggQ15@?pVWe36!`};BD261=eeH{tV z`vp$<1A|~mbt7yH?&Z<`nfRzqAdoQ{%RmK_Afkew#`*91=gys$hmM1w3 z8FqvODDY|-eq<=yGex;#l~x{Fnk7OL3{C1T_SOp~>-4LFmIjrLF(%ttX<$6+xP>Wg zv-y*YioCAeR}Y?I7Lb=3Szu@Dq;hM1(OL}|`lmb@itIswqZ0oz$@`fbVFD#XCI?g&cTbm%_Z`uX zUeOsUZyG7RaxLcKV~yW9RG0-e1c-}m5M1HnmX7Ff)E}2S0eSZX{|qRrYStZ?e|mQ@ zLvo~B)uUEu<65azt1N04DJP{RmW;6awIkds#hSrAoF8dvHX1ZsyK&?)j+o=XcWZ|9 z6ZKxhDm5UWYJ^PeGp+piARiQW!^R~;Ou<7OR}2}yj8?4a<5YI@6uC!jU`b+RQxsy( zEQTL;n;q3K0V|6W&8ns(bt*@$t@s6jhh*_SHzTfNFS=8rc6RV>IkwxY!=b2*5~A zkTqA#A--@a{VL=VikEL9(FDtu{>jL?;S%^h%_s>`B_6}S(l6&1l$)PERZ zv9Wbsv6rERS8d){wy+Vqr>(fB3wUo)|DV!iNLpFSx`vrVg>Zmdu|Y8w{6 zzL?)6T!o#ad{9;2O9o7xJ(2XBSLXiWa>4vLmmhadMI7$YBu+xX_Wid*$7o(V!w#X_ zcMsL~H#E235?|6S`Y&)UZk8k@jQ>ur!!J&(ZHs(Ck<*?cWOL76zU5d>n33i$vy zNK~*9guNhTga|(B5u`cbVN|hoMEA&D2&bbb8EB^nR?EbK;HN4VMU%M(jlg4!MzD#s zAg)n8xha4KVHGX?bvnA{s*SbuwJA`*B)HPxM*WV*f&NMd6=}QUb5%Pm}d4AEbh9H`#vgvGjAU*$9G?WA%l@;Lr@qkeaGM)9Nk|PwokdeKjzXa{iD<_Q3_i|L{%SaN1ge zTDMRbLGsh!n-gIrF(YOV4i+zr@MPdc;*$V|VxI;I344>BoWt0q%$2{>X~_=KaB_lI zGC7d6%F46B&(XgSj2bv?25`g(tQ+a1J(iaeQ(X*o-&2bhqk1~NFY$xNV&;pwDS@HL z-|`r&l5hz8QmdQ$g$k8;rJo(t=p=(DHv1p`XKO+|V;-+6Gn+2gN*y*nCvYsnh`{@{ z_jy|;)$o7Cq^oNbrRbUqw_Gheu?b}AYPNp}9BQ_5TAT!yNdPZZ;t`>e&!Jebpk04K zb9%W09P>cARLGo!*5IA``qKo#p~JeiC0%d#@H`X+Hn#65Io(qkOP0D_WT2!Akd3Lm zN!<~AN;vx};Nf}@BQKt+Xb8+1hNqYZ5=*}NqrCiy*B<(MBrd6wzEV4-rtQ2kKU-N# zNjHqqHL^l*8h}gZoSd}*eteh94UhGIWBSBSy>qJXJO9$c6zjZaqIC2_7z=VjqzgEhEX$_%% z7CbH_RNqG6)|V1l)s=9skrgDvU2U2;Lk?Oxvfcn@sDaAmwTC&DjRR8NA&7r9BW{No07+(BI8o_=2=%S(>6!mp$75Y^ zO+Gli_<^9pDx)dk=u9w8)0|-eK}^N~6nw3$SCB zywyI5sP=;qxs1L;QO`5^kO5Aq3pu23m9#%~UUALfdX&QJ=+n%!9bmyTsyNZ1fTaWA z&_+Xkri)O?#CAe<0DXyh@MKe}! zQvK81bCo?c*IBC*`+@Qbds|?=t`DakbO=3l;wpsP@(S29lyHJpcs+wTa1YI2RxAcq zRb61`GLqZagqBdQ=!&4K#z9S`9CS@RsOzWQ(qV`gpKIOL`GV3Fp#px7;xOB|yTeXB&2-8jwhQOhagj|q>KG$is$VI{7J%&6&F zNGYQx@@SwgM8ks>v!SFMu*V0-dF;ZYK;m+or@<&YhL@luO1gbt1BI%X@A>BiB zEJ;!I5XeGAR95oHmjCb99VS;(;ik&np91fa*i@gVXrU=A%OwmRAT>PD5L-fbUeLoW z7D$Rb5Y9ihxM)m0!pYaL38tp9K|Ue%a4GmLBT5=8pNnuF;|WD!(lw_BXGOD)K&g5+ zGJO??WR1Wc{p82|z-iYPnQwqwQX@}n@0qK{O-1^A$c*on^YtM(oII3oW^d}^>TG6Y z2lrq0Km4DKizo^C7Zd~wGaG9o&M#3`pr-u)Nax*u-br0;oKYf&IlW!7)q`42i-x)yZsA5(R|J@1akhgh$+-)-u057tlDgCDMI)NRFefjC!y zS7e=owJH!sw_0Mk7>XEfs4+9^4C?zzaRMZ~LFFov{3k>QTuF zR-3k&xaH0;yVLi(fW_#bR96Eapgzz{!&^pv0cq|uUDK48E%TqaWsY=MKjnicdoaac z%!6&zePVscK-h8E`zKI-5*^)ZaG8bfvqR8+t?3WCsKDydO&J)T&wBbpn~d+=Gv36C2dm zXO#Z3IVo6eP5GH@_e2zecP8*Zyg1oe)XBz%viT(!{k{k9ouYz=Q2PUKu#0h`3e?AF z{B*)apAI=Jh)uL?Fk5x9;UPv7@Y*PvqSv-pa0%bM%!%3t@yf-B3#!GOS2gW14D{go z>&*_@B$=r2(TX&m_~TH(aA+Y$CWLdCV6-H&cw2J+r55Y!5AB}${-bo56s_D-$ZaZ_ ztCcy^^pyrS**|6I?2xJhNzL2CHQWLSxM2}&hYGlq6vGW9se8vAB_s9ZSpI%nU2St7{lnt~R-Y&DO*8=rVV;5O+)=0mdGTm-UOR#X#j)Y3c>#B!kZ z)gAIZNPjYoqxLG4!NiI6lg3Z;`__YP!5OI*cPc9`4#WqThsE2e}wQ_&+odbpBFisAAeVNOr$hcMAu~LAa+?UF6H~t$jX!p|DBSJ zK_AT0HM6JzzBix$mcex=5`X@!$Nxy(#cUbX%xbfkvlf`zX9JG>5)C-cq!7bPOJ zfl4i6VOdo8do#GfOisSeJ}jV&EQNmwGrj$?Va=5oh$f^HT|9Pto`pW^rjP`xCjSRF zJpJzL?K|TT!^i5*4Q_UyjIzXbVW>Yt$OHczsDf>rl~0KP!R@lN)Uxp;%4@GM2dLo3 zKA-gXh^Ng8R?Wm?N>@0Y~YfWfC%39%DWH;MT{JlHM zqh`g62QbxtK7L#aKsS>aV#m zTLAsVY7=ETOHr7fj)79IlQ7#3j1eDB<-K|H>w)p-2f)5N;pzX|?_8|^SLkKqU=G64 zZpG3D9fk#V>)1GKj$mF{d_`7Al{hOYKjauKU^rqxVx13_R}s;7gb2B4>Wp+wvX3_x zLVewIKXiyPw99O=1%Se1Bb_*1x1R{KIarVtvKs${^d21_UX5?yxS8B3wrBXdyEyyN z57Es!4=1N@ZDzj$PU&V@NzMO8(Q!6rPLG$5c|HRlk2}#vSWC)+r8%RL7NRO^a}D%2 zocdXaJ+b}1FPB_+$E-%2%MT9I47xial5mK;QH>e)Vx+=E7aYa zKDPsIuzxgEo?k7_%~0vay1;GB%dx)9uyQ6<$epMKyG0HcMA|rlq{!grxHe}_vskGG zm;I*S%A3JpMV)pxaI;Te`~C3h=X+8zKUKyj(hlbVN^3>Df4b#&aXr^zb1$b!K8x(0?Ca(!U=>r%A(i`SH;5H_YP1xen6!I7ncTmdrD2e0vCnELydD^`l1}PgI%R$HP zs~d*19lHVdm|WvUOL`Smqe1RyY{FjM^%~Ne5jCy6vro_v*A|2qzrkzO&F$l#`(%u71&q+Z+dmjbxe~vrb=;Xr zuT8&t+sY3^ThI!j2oa%*t8P&-ZQ7AvJr9#;3R-*{4PG!jmd@xe9lv`d-EuT)=1F>n@%(CU zJe9Azo3r235rW9d{o&^Z4nH^0{^#TJ0{+$I>Ftt}GELJy`^@&72nY*Y!)Q!qUB6BO zh2zKtlcdds$PXRGtBz2y!jLJ>-c;MYl@Aw=zJR$iuj>DU3?LdzG{AoV!sPP*IHbN{ zuI9tS<@KGzyna+fS%429Y{O_k)fdf7P&sFx+(A6&neAr!^FwA6_u@TcJgWD{Hz@0H zUDA&|EW9nyk>LgxIPw7>5~W;1>l+_LvnI-;MVKCwwy^g)WcGtoPxlGFAW75ClDF$N z|1k?|k-!Ak*GDg;n1+H7y>?`cl(B!h!pF zOD;i5D{)ARN~ceVfqVB+NNq|eNgGpaN)#iQuURgc+hz~R(Fw^$Usad&Z`e@z+xx1Ljr8j)CL969rhFb_G}O2F zjrqyPgP4#;ad-k0(z|bla$6psnY$#S3i$~U5~P6t*d5WRy=G3xM953qa3_rfTn?V) z#BYlE>w^wP+eIJ~YX*9m5>R*xFi_IWYDIUh@TZ_p=gWz*B`2BicnE3f!Dh@Eio7&{ zYRVQZ!-CIqx+O}xf&#VCS$(_2cL2jvlQwwdx7YV0dheXD9lRN5^7nw0{27OG=-f;OXv@7OVbw(Zuq%KtLFXIZS1)88Ov$Py)N4t^-V$8D z0kRr986ehoh$7q1Lt(beNxfDS~BrNCg}cf;~d0{*p7oT_*Mr4Dz(o*{5Z{#sos{cYUS%TxssB-~WA z>U>&(D8cpDX?KihD1fHDIOa;yu=yIA*jRgeq#yVXif)-Wh*E5%k!`Z|qe9z06-gTO zIUo0C8)`3P5lr^%A9s?5At8K3_a}6E=@b?6nVEZyr>c-nEW5{67c3?xhQ8R#Aks96 z4@O+dre5OVwbU;qo+Qf$sU(<$|+K}^vWpt64Ic5z;9?8ebEBl=g zQv)Yk(XI@p3DGtMhBoiyQdr%xn*+5=hnHZF`=?y18FT%1|3KBKs^v@|ff*!bF3S}q8oWBvT9GgnZh7#oFRY9|Ca|j!v=WI^+f$LmEQu zkx|22r#^oSt@@_{dpp{{_Scr89Dp^9Uzv$(4r$bgKZ=f~e{KOY`amvwh8?zdOWWG{ zlUmUs2Y|^?sT_9nF3&(4EpEO?Vh(CF9~0P;BXjKw* z?0Su*kHw@$?iqNvq^~Dz@^Zi*2~2z`e7`^z5xw9p$Ox4N$9l{-efu zS9B)+uh7PDa8T+}I&LQlDipfW+}#xAFveO=^iE62x@QGp;~sMD-3Ba9Tif^O3TG?h z&w1%@QD+1?VT3&0!mJoC&owpy3;f%Esp7=8V8z~qhZKm*OD2;-K3@x~+r19-dOutx z2lE66EtL)%NDA&Z`FK1ob-)M3fN6BxNWV7Ln?FGZj~FSfPak*P1U?scc|qv&qy1C2 z#nxPwuzL z0fSqinoEn3M{Wli??JFpKF>!N6j`~kHw&eDvw22p7Sz~{5AHEdH=t&UZ10fp2dzSr z;1x{yn>xTaB-M6tYLT0RRdeZULUWM_Q)yp3%sSPqI{?lB)jJDMO)^%%gLN0+-9N|h z^u~_C{lyXLFV-d5V1KSs17G++oIbK|Kw1`)}%+#yvO+9;Iw6n}#+u6$l6>+!k%`|rJ zDZ8$m(cIp2_g0hnxoL$AX6Qxv$C~EsDgL`_7c+`KYmS!!5A}n*uMn(LIL{vrkYPX5 zdKRX(iV(qBCXBIRmrV*$v{v`7f*-#o zy76%+1a53k62jq8$s_s$1QvnMf!6ieZF2`4PddK}-{<0VUq6sc?qfFV49wX^W>6NT zES#z6_^Gw3)met%9y&keuH@3Y0j7xXWYsDQfac_zZ#~cx8!W|e-X94%5fPhepbc?# z>x$%uxlc_rUjsA;Io^DNcnpO9&9no>s6LSqEYPajIHB}o|N7m?ueYlm7m40tQ>3aT zOOU~r+3-|lV&$e)b9j2|>R@%F9gAD1AHs+mSHySV=Bh&dgW9*!(*0W*OF1iei4woLWy2o2MBusn269_48Mw)_+C6E{)E^jAEy-zncBAI?x zx_WnOt2Zmd%R-?RG7y<>O7tG=KSf#xvs0KRu0n{)le6|+XEfPbV^7i7^Y)fc`k~ah zz|h;&Wh8KR>|rLC*2=VI`$GGcqOK<0_U!7MFmP1$=d&88d ztDWIcfw!AldfGntVE(L&t&_=T8YPwrjI0E}=j2?LAR{p|B=p1`yUE;&t=;TL^}9L0 zf|DL5=DaLHZim{9{+uqksebrTV~Ic8aeRJ*$k(S`o8kYz ziX{sR)Bny0CkJcmq6O&YJWxCC*C^`D!+>C*5&;R$vF(oJz3F&l<85&jCo>8P3YD`v zH!63LMW{|K(6^%Y9LHIz8k0U+?6z!8Pj6JyK)o559UrI={z3WOzN-7_eRmQ3?r;`2 zY<_=#ynn9~9zkDaEF))c&p3d5InSf?2r7kn#@cV43nl#^5-|&{Jq9!Lw zn@gf@hNK$*+P|^S2hw4r@r-xcZE{jpD1S=PZjx2AZTM;~nO&H%LK4@xyk@q4Kp1ez z&$p=iwlaKSb?j~y`C2rVJXIR($bG{?9rY)wDyPF9OkoYlB{M?|xpM%$+?>3g28(Q- zkA{yJ(Y>ACkY9j|J6(Z-H9Z-hXZuenI~JSFq32Su{e2ZOKpQSe0887*M;_(?tgH?- zVUAbxsfcm{!+IcDl>N?YCM=YU_=lQ4W6Qrf9{QcuBbK%-8Zu>yw}g)(I0kNM?==D| zN7fe+WmU(3$x0ij!Yu!p|9>CNWR*g!JuYtf+&JFHO8PsOZt?TjDZ=iA= zHz^wC)s1++3f9Z{=TkYnW#aWMxvker3P2~&IJm$!KU+)~lRx45juLN*#B!a6kpm6T zx^!cI0a9k9^E|9UE5Z|VeZ$g4CblZ8Ax_ineMs#BZsR5n|a zEP}B7qE==UrZ)U#T#U;D1&YV*933Dr;XTLq-v`+nHC~B5Q1Weq!Mj5#J+8$~oAmjX z%ne`%vI`@XYKsywBDC1hi&ujPR*FyHj=3ARgQEhGXYlz=>=`x>;qv0s9ajR9wJVYD z5%N(kV%EB6ApQXYK_RY`O|lAy07>DdMp}rcSdliT2hli=0cWfMEy|VF&(sZNSUZmNgFcA~Vxc_fNSRxY5?4Xiyca8~iiG zZc8=oipz}e0hp;3u$5(2*c?O<=_VfNxdGTK>3OWR9bP;tVL$?nTOwck;YLsd-R0ki ztpNzB9#U^?wU;9Ag?;7!95T;ELu&GYA8)MNxVzeh4VN8nBqQZ!G*+L!zlswj2!3nA zHQ9Gxp^3qUxXT6faVf%24wXlSQab#IHr@^wCWP;VuxdbV=P3~{nOOhzERb+aUR3{qccl5kh4P0U`AOf zJ)oa&m3bFSjH0!BYb8od-2afO!g(TY?7S-WS!aru3`~U>bu}3!5ZMVmPib75M1`wV zw8-+=ZK4jXyS$RaOs+J`kOy+A+C*0rge3;VmnTy;&k+Zppfk0{e-fsDy6lTLwAYF= z7=>M$N&@;$oC6oFNs3AcxiVd?Xi(e&hraHJtJ;5r`0UNhalrjYo@;lX^P+K*6*1_M+?{Gl(>dC5X60**S}lm zG1f~4S7}R$pUSDXtkPYb!2~N63>INtV8wlY^jmbi^cC3>>(xaE=;jtBKu)-}4+@4f zQle0=xUs(n7JXG=@B|wV+6J@;@&JC$E zlQ0M4N-ME8d|o*cuuQiBtAEL%4pap1Wg-SVSS)soLq%*GTEQ53!+xeXKV9H!Fia1@ z35+PwcAn&wSTf>B03>3-Sy26XH|~%RlVP7H={E>xWpKx$)YlI@HoKeGG&Gq*Sv%*> zQ_z4ocqpW%4(}$aMCI&4K0gXsDCEj+r$4VF(&lE^aOOoN5co$AWF=u$@xEiJCNrv| z&5K_Grk@&!hO_oMg%MGI~6XQ7d!uCo!pp^JwV!G847y$`h8pQ45MW2RZRaO-P0lW)Ud%(BIAqz{MBK3`ZVV6IQ0C3GBm?8y~#8 z{O`>nge%;Sirjn;7om{`+DxqqCguQH8ziH%X!ER}Tdnwi%$?RNhPfr=TJv|C@p#qp z_N~)UljDV{WY}}h)vVaW{u4W5;7*i;H#k&?1$eedz-)QMHeu(Me(VBzzy^wMmPkpy z#qN7i=UWe#yUxfl!zf_=YNtAg)_*fGF-ZAWuz-gPJHpq(_mK{4+#MrpUc?5^p(YHA zJPhFjk0X=cp&LqXJN};@(yCqkRn(a+T7^17W~IOx`7*)z3HfOcDz5tGjMLEhRhLVW zjs5r;U>#-ZG3utF1a7y*tP?p755o{3{@k|I(n@Kw&*MwHu#jej5YtzXA9oroRrT5( z(s=IIv~%k#YT??7FfhlG6jt<$yCd%Syn=N>M~DlF_&*e$lY{Z>&^44VSA+ex3}=h= z%(n@>wCm@{AC3K{P&`SCLE zB4M-Jvt{0y#Sd+H$H0Nd=nhNhEa_v=x}=AXUFOJ7Og0p?)DD8?c zo=SO-;h?a;LO;zYms&_Z-?U@~sFiosBN{=5-@QUg=Db0cG2m^wZ_=m~=3eOtNpmAmiZo2apa(_o_Z4cLW!h`34(fosOq3W?Bt(| z8`3@XzezIY%_xp zQV3Y2Yk5@>Jk|(k{wx6Th&f&MG0FI#G{z^tVncinYjRm^X!v9X!_qCl&x& z?FJrB%!S<%KFI+xY{RxtbMJIDsydI-)C8uS@Zi+3%cG<4{ESWrTL%(ETArj5(#T2TAXrI&iL_z+$JTT4RV zq-eYfh{Xc*(6Bz$VUIr730!XQmCtiL_hU8HqPvObfE^wLHFo*#}53mk`Esu z1+fW>Ob74F9$azVBo?HA72k4&aF#idxf7KO;UBw%Bo=!ij1uc?0{|^7QeH42rm zZrvRI8v$0Vq!_HFi;gSouRBmH5-Q1Bk-qGPo46hU@R*ywV@!}2FWU7YcW9Mym1ubf zQYi}EWil3PGq=$x zb0N)`NGUJDv;5nOe%YEva4g5D9wWfA25?c%;q ze;XbBL?aORFPF6Fr1HJV5k%gb*lc{zmbeUU&a2P= zN@p}xp#h;xF37UL!&_o&F^|7HMqR(-9$f~qiHhF#k{E1UKs(FaD_0d=k?9^-S*J*x zb-V4~Q%{bKOtv!pY$sZ>cOX3hDDzl*U#_$TKOY-!1v;ALFc1z)7#>o(Btwh0>_$8D zWWV35xV1SffMn!EO7h=3&}^ z#com%ZwW7;Ax5q+P7wU@3dgk`H4#T%qd>ZRyNB{wg#q*+?F>r!7#HJ zs$BtWz^vUy1`oBf94iI7k$2XLnG{*UWVBRuZqKUcpVPr=x%_4$^`Onjn7r7s z@TP<#t54J3H!VVD`8~~7D{Qy*TUP7&?RiKCr`0)ZHzr6B)6op|Dt-}(vXCN5e= z>+e%AM1p_?RyVb@CXh>ZI>-L_hUq#>Nz-a8WVyU6VTapB^5V@LWjdHYxQW63QvN{~ zq->Qmi0g^f(vl@i+L+6nEYu`S$LHQ>TXA;va$6MalaNz3ejS66&cfH*Cg@grKRN;$ z_5zcS{7NJ8vj$ny7776lJKa5Pd>^}vb(*Nx(Nd)$LD+n?>O7|l!$%*2Ku_PhYt`Cn^x~FM-9dwi zScUe0rCTx9n?OsMssf5g?UtnzZvkzAO`uzD?;`R60KIpV=bvDCM|#)-bwXA}+cK2$ z)JAlPZ>86U?(BtCTXLvsM%0d+eT5m94*H0d4!_m0<38blyQpQ$UQ3?o_?od_H+@;g z?73IG%S0AYa?~8P$2Q}IiwHBN`iA+;Nz}ZxF^%I_FT2r9S>r)ATSa@45p2O zeiV}gE?}Ugb?*y&H&4`DC(&oo_J<-N{)%y?0cnLaF?%mA{gm$a`YRPPq29fQE!N`b zJ!vafu(p2Ap}i_hVJH`P3hby%BZk5Vg6M}Ac&rx@XYh|wr;{GZPwIIi7s4fH@&;6D zw;`VdTT|XuaftuTPsiLM2|o;0j*+?}ABjn1cymX~`9EZxV{~R=v!-L)cG9sswr!_l z+r}H)cE`4Dqhs5)Jvp<^cV^bizh~{gdq2CX?z-zL-VVG^P^qpHs}CxX2?=Ja&br)j znEom=P`iJzy4l}03v}v_vlW2omDvinufOb=cDwr@@&()Y+1Zes0Qo#Pl!p|dUQUos z91hU+A{6#G_MQMKq;x$EHl{EWZ`h6vFn~vaM@sY$W}>i!7Oh`6ZBk$1FYP&7&JM9ARHuZXccWI~gWuvn$B&2R*X{VeXjIX)a-o?w6vkPz6e-!uiQNlD#d2B z`0-r7{y`C`Q}XIm^%+7%pg*T&>Yo!$Z~JHEk&1#aD=a*+pUBG_k8wV! z8l`TpIvl`eoT<^Nq38sn-B70xgo$<+Av8;H!(#3Ax&td)&Tuj$J4L`j5U(2%C7ccI zwkG2@bd!cyRafq~`Rt_}$q=(r;Sj_6n7SKsIv5FVKBq$OhIh;eP=^mVutYviP1*$& zJc$(=3~zeU7=tjCWI<+b29~`S@a?r=_+d+Nl^4Ji=q|cHWAjm*D_JLP!Cnfdr6{D{ zYf(QQR5zbyrX8j*fCOKr1 zX9a*?JVM(@+{)I*B(9KF)UqpbWFkviOhxl_%1jhiv-sz&``RCNo!^L$#s^*ePs0GgUP>*O%|j?Szyb$l6N`py+JlFNa*uQg zMEoZChKb_M@kk0GJdec@q6)^tPJfNa%Cw)Mih@_t{$L-vJGyTUh!B}4l|Sa0w9`-X z9CoKK&F{Lh*zgo?KIGl3df8vR=jNKP+VV+Td93TcqrQaz&!iZb@^9(AJt#Z*vL(4oTmmFQ zEjT4qVBpYZoS{DUC@}J7lE*e$2GamMF$#zxP~yMKWOqGVWsyxX6O20SROQ-=av*cP zz6nAHce`+O-H^5ubaErwM=k-A<$zBj{N$y=|1R7#_9pV*Qnp_ zSRudB)WLfQK?a^5>)Sjf1UkV7_-)SID1ojBHL7+AYgw-=k9{Ryl1S?H)-S2|wk@wc zWM5bZw^$7Ce`!8tg?)zUEfM3wBrXZxcl}P5|LB6eQs3zavDL+Y%9taKOyVwf@dnx^ zz8HFvp}()Vec?L-SuE8a&EW%N(&c&NClGI;8Ko?6fUyKz2REDy)NbN-VaXCJy{OsX zQe7YvYGeu}O8}cON4tl#UO}2=wr)+I!w_^A#BYIKrW{nRFKRqzby`1%NS*H-T6cYOZFe3vZBPPhyHi%7rMXq;HV*s5vbC{e?p0!(&dz)MWpTGC30OVjA9QS)J#qsWb>a zxT4!M1_Q@{xpYKG(Ln(#zGAx$!P-p*98gR-aBkWziG`>d3`08Y3Rf7A{x&oy*=t$f z1E5^LwsV!$Towd8p3=$oTczHw7HlAbl+q)2b4TGPD<+RR%m1qE3)tEyp(jwumsgXd z!@9Y%MlWxDzsNz)=jzB(xbWJL_PM+U%Ma5D-d99Nd-lmzV}j!AH}cPsGkmqkFoCLg zJ3+jF4zw_8KJkBp-=jCSrf#c%;DP>TXG#51`Nne3hz*rmy=)Cj+aUS61VCP_;Ri6W|JPyi# zPP1iq{L{fyGkUXYKK)|7f)fvNCPh*dk#y@k83nJ!6(u6u1VTj$-n=cIM+5>6-S6Rs z0u=$|O-B#k%K;vCMc|c07FG@yPfKxz_5veDpjfc*$FU*X zuE8-56A{&N3jh;V(e}vBt-ksG3*v?L!|a#1yd5}lNa44Yu6@>D8Rvvq{QNXmcAsm%B#0e>`00%Futrh!m@EB%F_if ziOtZnW;+aYj3*$t0YgI_c;=GG5r^}iD5TW1B}J-46jiZa+D0U&ln}s*SL?-WjtqBT zM)#6?gY2gu^BbX6VH;vohqW+1Np%PyAR3)tw&ZFV(O_!8oZyKT=+#_kjg7T&2BoC) zI1t{h{Gvs~A`!4K-|L?85MrSC+_C`Vn6(*h!QP@NY-95;Kf%DwUM?TPw%g7z8j1&8dujDx zN^+?`JcG5L@eqeGF43~xC<#E>AQ7X_bQg7ejAkyOYMQ+xdzg=CwH^IBx@t4m_t8(a zwcgVF3>uGKF z;N)M%fv*ET;QCxV*;9Xi5XAg6apDsRi;WAw7lZbga4SAQ=zpB>E-1x3zQ zR#3kHMZOn~&X0*k9f~-NVN6N4(Mn2Z8d9`rH*{5bGU1LunqGM8t~dvbkz-^&e2PVu z5#oIF$9{F<$TI*cV%2`dC#mG@gyrU9BNvpP39UT)=^<+qka@=|H+^46{mHb%3% zvNs!W_5T&ue5qS)4{|GG<^u})Ew$C$rpR&wb#(m#%pk?Mh7a+yDNz~=5hh7nNW5ITeL z6S8`K(@J-b4GiRpC+3~g#Ji~Cw5^rgow2nXcze;P?^mOKHW~#8i2BW>WZWxcn!zzW z>4}S)jip>G*2|-(f8gvR?f!xy{W?N8cji`@ZavRSYHTU(DKjF?(v@0kYM5=D z1qyo4WHb00FNSyev|_cXnkJd%Ubuc#=Xl6JgH7I~;*~FFF?kHFQM0_V@pYevT4x1B ze;tn{Dyd?0>8_=)kIKxIPV?FNPyhjVmsc$|{rMD;184XALeR;d)UW z%6(qz)O5v6;eg$RitMj?+vO4umFuo>lL)g^ubLQ6N;DDu*uZ*P5YCTYzi?t!ng1wzfZG2fgB&8#R>}c);Uc# zv&j14$cHP-ud8ZJZqvX^kwq*7dYuMk^ZQqGVev4iwM7;Vs#um$rdIq1W=X}XLGkFv z$@JYP6W|tE;lgVKh!QGFz1}f!>JjzW<23*zA7zvjO$;}wGYn(mg$ppcu;=x`$WN;S zGKH;7qwQH@38!bMh#OiYNdlavF($XQYzxA!vX>2w&mbEdmXhzFCq~VTa$X3P()9Ql zK8EIJ5$}>;m;eVy&_}rgAI#Tj)2Uq%J+>j91@Lbw`RNRCjj=gY@BO9VrALB?@(~FH zHOy)OUp~ZYZ+vgvI6tY=21{;7pP&wR@l|4dHCd-z{r$kTrs>H?MD@(vwb`At&QkX` zp*9-2vyTUAUnsi%LjRJTw7u8>=W#j`Q@SDu$$tYd9@_p($0Vc<|W9lCr2^B1%WIZ#n(K)dhEn*n@6%Z z?}i~4%UT|q7(8*e=^0N8Ksc8Ja(@y^y`nGVyWW~!QpEtaQa3_H&s5h>xvCjRLX(`- z2Qb~Wy5|-1=iAiFECim?>rGqN`uVUN0A7j3n(W*>JL$|WW+&1L-P$s9Hx06_@&oy( zz=6ZD)|WekuA472m7iU+rXEbSy6w-%T@whXJPq(yviGV{x?na` z>tAfKktZ*=7@-AU>1G(;3OG*EZ9Qj;UWJMxg)BZ?wm~Y~3@}}M8`TYCt)6L#0D^fs ztvqUOumAAj_Inumhx7^}#}2Lk;4hKJA+NxGP2`?@qbeV{#X8G*wo|X!ZhCHwa32-} z2$#Dzq02UMOG>J%0O`L8DSb+`7y1a>yVBG_YbUx8aX0uH>1e#sYIEs&kR9+m^&k)L zam#%TBmN(ETB?FM2pBBWe+zOP?Ch!fx<9v4OFDLA82QPAm~50E>xB$7U9E?3bj*so zSszTo8o2Eum|OUgF(Y*p+v0h-DspUjDQWDN&L{hTeHGlkaH} zzKai13Ch;h;DX3U31XPBpvC#qUC?YPx z62_C%O!3rh-&g`G9US?@(%bqj5rCNj%!Lnwm+(ZZJobZ? zvG(rbMl(w#56A`E1X*^-xeDw_{ zAo-0)P0IEH3~naGF8~$;>}I}9j7$qY2s1&x6I7({^L%Fm)&shoCpmcE?E$DZGDpJj zzaj2L+Q=w5thnUFL%9P$?+C_%bOd?2Y0fq@vKr015at80b$r3WEPL!va7VhLU=c+Y8d`26m#IUzg#Ne{&)Qi19Eug^r$J>?95jqHH9NX^wh+Wa zPl*haZ2{5j8RrjJp8CowB_R&0f5KVtPi&2<3Oy3O<8VIbnuRWMFUDFgaU=om?v3x^ zO}6PLPX3km#kF5B&Z%-PY=O;KKrU2avDF1uesA!`f&v4LEd=}GGr2STlICU&EF~~f zO{nbHd=(G}%4sN6JRPfwyZ6g}D(hRCt!GCZr<3Wvp!pPFs0E~=nJVJ3PJoiX3jP~! z_nHofQ54Mpzgr9bKv->d0F5>UKd<)?arW6dR^p&WXVbN=I__Wbbx$lMm~yfBY$s7% zeCfz~DRu$lnGe|a082)NWND;9Hp@eNN2&?`-GvZha7UO+h#%bC0J0-tbn=3c!*7OA zP-TSe5A86(nIlkpo6ioZ!N@xrzAOs&8VM3P;zib1gqBYXitTZd{-5dKo)i?*=UKgC zupzYJT-5_?gcBCWvkF^S!E`R?b!ubVL#(3=Tji!aV^A1K!wG3ToIwLc{vB!o@%NVy zi?d~=`X|>w(;UCoTXUeU(@)Sp%w7jQvAMERjbVtHn9DCsrY=pzqk63+60PQ&852)Y$`YMPI} zi+uP1)G3g92r6yeAklG$ylRgX^=>AVa;g1+U9te6+f*#UtH2d8PBMQN7(Nhwon?PV z4^RVMWjkRnXjXV~kQBbWwu4B~k;E;O-v)74%q}*Wh_dFPbl|l8)>raLZ`Q0D$Ci@~-?+Gaa4 z$=^xvdtHVSVGzkF_jwPA$wx(YAWgZWGZEnf?k=Sc>i>Yn9Mz#7` zLJf#F!IS4Ga(rlDTaY@~!-@y~JoFhmq{a5=x7(_2~&E@CKsPmuVI*3o`m zE-^%mi2Ko}4lp>&^_j;!f1b#CcD7bqbS;i1W<}!3a{Sa%($dSO=uA4>ymtlQqc-Hx z^JedZ`50VWgk8F=cwjp}$_t)b?=UH5`*q;i8Kr8&NhJ()>-t8$Cd)^p3SB)D9wRlE zwJWGb?sn3|av47@ZpiD`n=@)??joKaq+=c%C~*mqJd;k2afI>z zitkMon5{i+kCkAB$;1m@Y%c+9Rzt`w{t6~{yQ!E6vRuStcfl=9$GKZtE=hYx+FKr$ zp1MjSy1LoT;{{iOrVcG74taW(P(I720iBeomu6AmOG_LcM8IMc)6G0b@9AMiZDZ3; zXwy`=IDD1KUP_O#WgVgT_hlbJLdA6{(oa7=cie_8V7+5Ha2u;S3UURQwqVJ|bzW@d z78wNH5g!mo!6rb%0(C?$F5QUXq31D<;P9_%Gf>6`$z}K$KwMG2dL$-h%@41*9LW2o zIvEE^p2N(&p_|w!uh`PL8E#KvBCex^Kb=9!xgVCd!}xCZ=!w%Ua;|%*LLY0q9pbw# z$z9scY4!2BKYQfID0u?>+3tLM4%qB`8~S#8pC;UyJ}1Q7-uQTE*DLWJGR#OF;Pxf8 z`v-oUaAQA_PdD#M<>=rN!NQpftw8u5gzNKUS&(_??Xek2UxyH$ou`cs{*Z|44;)r# zfA!FqTTrmU7ZgfJn6wK_jwSAXke@Uwk5SaUF=kkW(6P@cW}*RDV1B5S;Q3(nD|V`$ zUKfs9P%$!5Q0GWe!&=-^z$u0MhhlHPwoEsE6w_@d6iPD39jCf)ubN>y$Fq_l7>b*; zH6-a1ZznJX*b31C{_}^Kc1%4FaW<6f&ohB#l?xfM*lgB}qra7-zjkNF?Eu8mNkW^~ z8kX-%)t0I(^|Uu&UMT;E5ggjQ6>rWOy5F~an;#GtS2D%;gpSxz&Xq+)6KymTOO>IM z?~Ar&ipDSEBNbq2KXQ0=<@)L+fH?{+f;*B{GSz~tGpRq><)xVji88=uLLV#Cg6zUP z9o3=ZeQ|wgzTn-fUVAoVf|mFynpevIr@j~jGO8iEyM+`m3Dvbf0g4K2_Q&W9TPODn z2&r$uWQ$;?=Bk!=UjW%UUU0RrKMN;3h}kVR7i1}2h-BUvE&V9+lZ)-@V+axuIb{|= ze2y_s71y)Ds^N^<3zXsPt()q=x+ILQt#ps6=a+ymo^$3LvAj$qXcqBGullXvrjyI+;2Vv3TiThIb1vPR9@?%bYRXxlV0#UueReHylk} zkU72Jnqxm?-z`Tk#`ireYB_j=O*!1gBU~&kr+VLJ>CRvfjV$zsn)I zL%{=dzQ0Ju_jXJB2YwRl!}J2P2p7^9*p4&O0$mT(&QQde2g7}De%YS_5k8lpDQN5& zgu_1au$f%7D|0Ld%JUeL8@ax<@}?= zWx#KGHa)gPo4Dn9kfRgZzTp@ogpHj}rZ+1S4Ped>#tJqc6M2;aNj4 zwo$Ol0pRpg=bLzM#?zH&kayL%`SVp-5ev^bfkdyUxOGmfSQ~ zdw6%~aLl4=`tOjq*few@zG3KJ?w-~nbXI7I^}DVUxmZ%uCoE(x;-Q=DO`Iq9Olmns zA91o02JjZLZ|0Sw1mvYa{z{g@A})abKANm%CRu%3^HQIJT4foeR3T1eqQlT;J?Et- z23VSFHZn3EaXHZgh>?Rta96kdVesCgRI+N_^=46wSoIZ^lg+x+AfUmGpub9JsN6s5 z5kZRQqO2SPvhud4LiGRc5Nt?6qKQ)1eo}_&OW>RgA#r5?yS|ubS5E{86q@l3>iG%F zg&`x|J%|K=t{M?xcee9*dA#m}(OXUH0=}4u%^0@VzPmi1alZcea=-3fOcik-OJak@ zq-w2sQSYo5N9ChUXa5tp4iV4(bX}ebfR;kia`!wwG>XcDIRu@x!Ck>b+q7zp^c`&E zLw>L%KM}@p?L$!As0s+D%A3+~$ZauhJNI36ZzxG7OH=n_ympBjBEk`o|5pH63cyx@ z-Xi>Df{>fRF}cOv=|mSJCQoPzw(esMDQ0-TM9Pth_z0oF4@b&?L-i`Q08@wD4ODWj zG`aDC2Zqz3=IBv@BgZHdR%Jd1m4#}Br&@pDTM_)j@;i17kpK=6yk;y=svvn+qQCg` zt>+ESW`$B%8NOakZHa5o-xj^72mpR&w_My7j+!_2N zXjrM)k?638qpbi`st|b#GoFKjz@|ob9$n|}OTPqLLktA)guXB_!bB3+uh=qkiO4mK zy*3f~ntP!^`b8UwX?DZJ0ntL+avUPR@C=Q6nMj~5!bnV^)uDuhZy=z0Yf0b;#6{35krYzIXjGIS*H}&z z+B24Q({fG!)pfRBLDcy88LN#K$ml(ET+SVR^MN_EvYv6jf+n9J0%D_5hOW0**ZcIq zu#%ht1xy7N!@_f>_LERwTEe^!H@5B@=0+6?j zwsm2O;1&o^WkGpRHC>p2V+Kn)jq5fq)PJH3#*>j$XN0C?3*S?@ubVO9+*J_Tz+2Yc z>(M0F?94W&d|KM00mxeU(wH}*oXpir!p_>^O0PZ*C#E`K=s)CN+NH`G z+J?ACk8@kP^!TKd=(WTABlHa<7+t(Cahe z(oDbF_`F*>!fh*&OH8S7jU27H!_c_drr3HdE1>A_(>y_%Ii`SL;z`+=y{2Cv<3jj#I{&5i%OVvZ~`1Z*(j$oStQtB z?pg_n(?b1tflMikbR~ub`Le2cI^hn;fN-&V}${37y zBRGMT^{prv1TA&q!xCLcBt2K!TY9WxJ-eQ7+Ti zyb@t7fIzV#MY1X^Oml9;^<I~Fv96MZ)W_P&XqBxSn7es>_g@RTpQUU( z*L6qS>rP51wjNWwXVuUJM+kZeO~YgqUTB{($B^wZ63{d-`Bv*;8jA994N#>_b`L{D z`UVL&9K!(;dh)0p|5b*l0LuoWOTU46yz?#>AR+#?n^q)KNEsTnb6)`_P8Ax^uQ-a7 zhP-4NZs&Yf+!Kuy5`cxCkvXr7KB?(o-BTP_%(3?6(l7)KqWob@nc?x{Y_s=n+4B5B zq{9d+|KO_zg|`#ItAx5(j^rqmTfrY%!i!y3z~airx~`6G^e{Sw>kkb22*E0&PGqkE zkqDW3Sgtm_6KqIDz$&HR*vQNfb)xIuP&)*MAierS;tuR2bxDuP0mm@Hc=b~cr&}X` z%{AQW>Z)0b3wUt+`?5N@*hwh^B?XV+z~oPKeG*v!B=8z6gJXzV-BpDw0tvyt^5fZA zk#gbi;;*!^%!fl7#Kq1#)o7DDTQtT1rYB?f$qiimJn&Vq3-Y!t|K8rGW-2qlf#}4O zz@m{w>fB`cpLrqriHS@HnhgVirHLpvq6t=?jgC1vYrK@1g&uuJB-bYKJ=!#%`@o@^ zRq}G8ZGo#}BZ7_W^jxK%)A5%jncqfl^~)E&_%;LhnB4Kw^~x%i!R&ExCr>3p_GlrHAG`Nc9-tCXCXv84@sv^95Gl zIb)XvkMye43BRGF;hS!4mj;TM2aYtP#oGe!9nX~#^&MihEHc-JTBV`Yr0tF*LU^{h10^W?vO%pqQID$e)+5Fo1^bK>#)lvlQ^ zCM~3m@H2PlyQ+d4x|%YpbNB>eq7Q%n3Sx;YRp!8Dkg^}83X_+Dd|(OyIQc8=^8Z+8 zsdDDDFs02XNto_}AF>CMI#$37(eAIE*X(qVsNn$VjSZA9G+>xs>HKDPfj@M@CAIbbzMOhZ&k4zt>xYA{IT zA%3}9uWg%MQv8dd8fnS`uyTixN!H>z&dv3zD8X9V_YT<+3{4>15#pG zL0nH5;5JrRZcK4eU;z@(%ax4(;j$xB5yP)mD;m2t#Z(Bn3gs)+JjH`{zP{aPo@LNj zyKetR?kIBhuJmtjIak7R-gvONI9#gd%W5#*X|qd#4mQZ5D!c^&nDf;=^rbbCzc0Ij z@E2^ebf_3y`+MK-%!NL}R9YFurV5>gP0cLkwZ~|xx=SeWpB0~CaLCCK1}=y_58J%n=m(t-GKXC}TpLueVVt@)WWtoh;%GU@=da;}= zhjmK)dlxF!&;6sttbv4xO@|nI-uYV0t;VT(WdGl}pA1B`lej`EpAk9b$y}x@) z8&2H5Js$@S&lBJsYJC&g!i2;zMln{C?6~0DAiIMtZhcXyGcqVXT=;wl0%V#49!3Y1 zqbMqj8f-g6gXEac*IUKGLW1#&ga)x~7)&QH*D?NK35|)n2(=-j069u^V&2c;xo|4q(TzH6AT z^ooRevtb&uvTj0S%rag&VcMv+=Okn|P6T3QbX_(I7#NE(T_Jgp>GfXt`Xjs+vu&hi ztf3XpdHCQW#W`V0kjg8Yp)>-Wm+fL&Bnz`k{sD33*7wK~nTFk=NcrlA zTzbLi%8$Q%VGy%=n8at6K2sc zvg6$xt|C9yRkc+^{0O-Pi_wj0TOU*Zx#ce|e`EZb0ujIS3uNHqtWZMzppjO-#LquP z&_)18N(V<1+RTM0-*o*lNs|(7+N>cTDj0BZK(nrLM=+V`@zjnIQ`2X|LXpl-(Rl$E z3r5rMd%5G$c6Xi)oGD)!Z(Y*qg!R&9GVpfQ2Em#HZj&~OSFjRH6rWlWNDv4~OtZp% zb?tmc)_0!Th2Pmga?z$t^oZW!Gkx|`t%(E=5c_aY?AI8{`YsD>$i87Oft&&2N|B=h zn4&n0O7!t+iiGuao+f@pQ%fCNX%wxF@<#Y( z<7XVUOrYTsM?oiv*#$HZC!uYazEn36H++wENgWjUwEYc4CiflmpXMvu|BzaLRDu5t zL;Ngl`9J!>@Be=Kf9nTq|64!6iw7|S22Tx&2Vn$Y`81Xz_fZXXO$$K*i=}z?!EeIl zbo=elA}ieD?Nnc8-o76oCPC11%0s^Qtn{Nr7MS!-_LYsS*K2>`n>ZgEt%je7;X;@>Nb=}-9De_XQFojx0} zHfOWcwD8dko3-$+kbj6x-}yvD8I{b`@Jf`6C?HQj2oRE#dDK^BPU{!B+!owX9f0c& zIIP4zSEA}k)=O_##VZy)SV_{sB_H%&RM-F@&vVb0Jg%7ntgves#kTDO)$n;>m*_?s z#d<)ri*jBO^`yrA#r!plb&ds?VcNdr!+j3b9ytJe z5%?M8dOJqj9ADXrF%JhGxpWB}tW@mBX?E(SK^6ZZY><{&e|`F2;_XeXvEC@Y=M#-~ zd_~Se-9IW_5`|GV-A7jbAEYdtEMzs0wi#d0(|o^D^p}ic2`$~@KV74`JsvgdE}x;x zh6ZRiM9r{<6sL4~23AQjp7aTZdR2h(!!sw|*pX(fFIA(akAv@O-=5;>v*NF!cAX)G zn(_ACru+bSi|O>rcS%xIv#{`2L(<a^_HhAi#rv-7 za!yJDFnQyqM^nUCI~L;R)A`l70#uLS_wm40GDmZHtA#F@O1g33ND9@Zat%|?#is?6 zr`P)-9F0Q@V){XZpORFBM6(1{<43U`ddaP5e`~X1id*f8E;++~;M5B3AcoIrzYJDl zW5d9vCP*DQw)jPf3z@-KFk=B>+jsLF3C_#>lS6Dx!pziaIpYr$B-Atv5a#|1jG1Bg zfy~H_|GG4xCx{2Xxf?bUza2!=2hub`Mej$3$+E}6xf7oZJU#2 z2I0Z@IV=jU%imv+YYueY|GBjP*PZ=uo)0(-6C)FQDuo}2aH?xEh#PQc>Qyob5wJuH zVhYG5C|DR|v}pYyN=R)GdmUq2aQ1}sOEQK1GUm2e$QA_*3?$PDEx22w;=FP?xT23*aRDPWmG z3Ob)T!RFyIb-m)?=<2CKQr1kvg$Ah%DF)9!mkxpw-49F^f;A6W9B#s1h)jg;p>9ph z22$p>m3*{ZsfT$NI$44-Ox`}o&@i!wjzBx)xzFB{i3^cYI1Sm&r)`DSXKrz6@NG1* ztg4?WVUE?cvVN&3n5K}ibhVd37Ck?tE2MBhksPToS7-Xg@=Ys2q-LY7$6`f zFSGJaja^3&byhezUik}7$@A320~%OZ;JiRDHJLQg+4`{U`1}2hDSf-k>PE)TqwM@Z zofIZmi~~}U5yUD@WRucsE+C0em`JICR*VAJ(k#_12<|3V~nHv!-lrYBGt4@>moVrEQsI0g%(7D`M zGwiVt7<$x`r%>LQkynR1@k9gj!InJfhFjf1ozg1uoa_TF?H*G5l_pH`|Nov@SpPfP zu(5FdPY7aRPi680K~4211SbC>%dXpQh@otn5wF-`y_nb#3qOC>zaK>6!M1te1Fr&s z{>09rT~B&u$yJ4J--^}6#VqU?TD$ySKk&xUtFv>)mu+ucZy|>;2 zScrGBBZtQJF>C&IwQ+di5-ij!q~Lx8)AZvk*AC-Vckuuo&pxc*-Y!B3eZ8NQU%HNK z>zZEPucv)sBZV;gwZkLLzE9bez){7Hl>u*8v|5mnc&@WrVCTgk7m0H+#r^$D<`I-4 z?i#lNlJRUF+Eo)r!s~!cTbR5Pxpi4UJ`Jrp!7_b{s$B+Mk{TW+V0B@6*+6r=A9}6z zEZ?NVH^>z|bXUN7NS=yFz``HSKbXtYEu?MZvJ|~6m zaoOMM2q<)p<9t2G|Op0(2F#|-JjNTJP2 z{m%K>Nzy5yks);o<9CR5bNa{mq~5w*6cJn3oN6Aw&3^vbCAD^NbPtjAwo~-lOZ0dV zxxSNe?iCd47Or6R0u&+w8${OSof25C{9wA?LP`t$G=W{QH4 zV8&E=GtG9*nJc!hhbz-7`%F^Q2dipuCMAR>3;+p4?Z+X@xO#t|SaQrS*M3yYgQs!1=m9w(8L{y*!g`SX|4N1dS4Q$!g6&#OGn7h}(AbXxis z7$D)}N(nlxSlwOutt+c1ELJrE#fOo=uzR377|yarZe+`LU%h3!=HLjn)(jDa97i*o zb`QTd;+U;uvrd~&*N-+gw+L-%&$$OGfMZ(I#Ag$iD8wZd@mYbjlBEozo4?y-Mg+4# zhB;UXyKu&n*KNsm2qT&8kZjA}Z@7L03aHh;Mx<>2cWZob;h_2lT|#2=xNFRPYV_s2 zSXbTV02itzo;yg{79+erO}^UWXF~*TxIz#STvwn7lm@#a~B7YGQ*?K;*S4PgSs&6Q*yuNRjc>HLjFi6~=(UL%6phXrZOFH-sSgQB(|P7(qZ z5h@;14TlC5p*o?Muyl#80OiHEKt#cPTJVbFP5@uSL`ZP*+wgOGV8JZh1Q5Zmy}9WJ zC6NyYfDwB*wXgYpVN7rra&J1)7RaSOF5YQSI8YMdf!D@u6@XR0Yf_ahQa?JW5?+YD`~O_5UY3OvJB z=_sb%X2TDFBTL)%zt*La1gOHpd>ecQtWzZB@5Y&}#kt~BvEPDKbL!X$R2KfpKlz?Ddqe3}tSAE=AFrHA(Dl&oqqTLAiQN-=?(o@GpRz?8aUqxmc z`~ySQO)xjV)T%BXRLcLXazvlnO#r!FPZZ7F2Xv|zFFCAXa>M1zU@y6%!baI`!lnP5 z4^oSgz%kV!MiSWh9MFNdcnQaC3`uK%3d0t@luX3#QrFMPn5bf_t!G1`;dkvVcl%l| zGv^}EUGfNlaPf+cL%2_M$BnB=dEGc`DNRpk4c1XvF583rXBlD`8>X+O*~)9)ClYBs zgLUiHX1IzAe+4b6ll(@9J+s1X2F{gN$rHgb3%3di^@2p)>~&<(D_m)=jF8O4`bU{KQ7<+R`u?g$e7+^LLJzmmGqC_d*HG+3 zkqmjzEr)+&Y!kj1KgvrpD1JeG@VYjj(A_lr!D`P&fji>34!V%4PCZ9>c1OemC#%p_ zasXx4SEWRu0PuU_rL+5Vj=X_q<(J9P6@>|z=w%pMODYr{VwX|CItIK#0-T0jChOn% zrNe&oXmG0idps!^o)PGACA?th^Z9X`(Ehw_=4_{>W{#tvgi4Fr^~Ky-g-~Je;~A!6 z4WUvSwo3XgD)ZnD!uER;b}ybM8% zVh4AopzlKv+S@Fxh4>w-Y4D*(1a~G~OtkTCK7cEVCog#>*rRo}WFe2_`53M9FEd=y zRhrH}M)%#_OGiKSop9@A%F?@1bfH5uaBgz!9d5U(KyUSsJ0E;StPBAqAUaDo?CwkW zgtzup64+Jmr9D$!;@Z|ZZn9SHigj5>;*kVA+e@mkiH9li19|!i7)UGwlppcXBr$pk&7)0ueH2kmqoSToMwJcWJY(YE|fVWX|X81*P21{P1!5 z=#kFnj)2pUJ6W1*A=J0R;c<~^q^!4<4~Sq)-$e@RKSBm07s4vO!sJ7c^?!zBNF)+L zi+%R(zYlQm`AcQrdeNaT8F!|bejWCB6~_?UV&+EUMCsK3$vKYKSg|Xf{OV(!PY?^) zLSV<$O*CPUiQmxJT`)C&A#Z*Ufw)~_mk39MZ06|L`rillus& ztZ&u!u2Ul9$f60qofioPt8C1^yT)Jog(QPcKrM=OBK{da>M=<<8#_X{MTy*e3|b&0 zQScT-#*Y=BKL-R|!K}r8%AKKV4frN4@kbF>wWCzmck^9g7mOuSDVCH`I)^-K-Qvl& z4Mp+GFqvThTeWmrq^p|+eo_vk+i{Ckfa;CcJ+c$mz!_-4qmE8pH{Hya&&4ib(5^$Q z2Net%P}Fu$4J}|LY-wYR^*tKlc5goRpOLE0(Zg3O@|;P_T7?>>EHeR0d|<)4|SKJxJPY&Z=suJ zdlfvET{!U@F&ApA?h-bY-mw39(98kay8t4(5o**D?vR=f-Zb4PjW_kaSw;gDHA7Hx zyzbnRJ)J0bVm;-&hUzYCwO%W?Lglym`^zbh@a?a{O&{Y!Uf7@Etm zpj5xaZgIT*vu6Ob=540^Qby$o50*A9v3aOwRUgsmYiA#h@}n`u+J7r9}DUN zB~$-j&bj67dfg!l?bwf-YXI89wOvZaPu5e7z$$l3)(O5*tYFX$4)vnI<{?_C$?>Ml8(`_?WAMdwmto>Z{GhmYt7u9 zn_B0bx~SUq)P8<@C~ti7{OmW>YF&M#-dukT%HbZX!MzlS zZg`}gwQ@H8X2m(b0c2Ikvr0tN&G&UxESxvq$zXTGa~z>9BHkHcSxyND<~we+KeVkN zPC6wUz|^aW!KS@k&eT|m)1>iKFZx;bCR1idyaWbilN|r?UPZjnRlm6Wz$(E=;IO>I zXqfT&OM!~!=Vd#a8^SUGcNDlA{4yzwK7PYtU!f>e4O<*I3=D>~S8v#>3$fKZOAw^X z#1^uL#lb_vvDh3-H}E_~34 zqFu7lrM zSRVOx1!_*11STEZ3RmwZ3{c2!=HY4u3|&RBJ4sH(^gOj(rY%d(pDCi+v(w>{ji=twc@!jRh8`;NXz@Ih!=4sLzyJ!Z ziW&j$pr;zdB*slwyq)EWB+EdX+Ql(u-ysKqJffbiis8(zv@e7tvyu&#xY@S(q-HC+ z8|3*LkdZ=AtU!j7`OXXio!#?NU_Cg{I4Zua7RfL*TF24@ zZ2312sH~2)H?TVd1oKoNfwVm`=iUN<@&oBz&kfbZdJdEVJ|UNW3tb)u#yQ zR*vKM{7wgM!(Z&r;S~Y~i1PB%Dqgj{)*gyi$Zh^cjru6WBB`CVB%g172D2b# z-li9+52YaDYrBE=w6EhFLP8fw1jPz6WC;ML17ZXJd4$`uR*L6P&L7CG5YPZMHUGo* zDL&1l8jKsL5$=VjIA!@66?%MTie0YILNZlWV{s3I^4&!X-x%xE8=Ru#H(%D7g;-te zr}#lWjoIAnN7$Q%s{}>1M&)FP5O5e=iAl9z;1wQVsVJOdlw!KQ<#quDzMnpdjNq|W zy+n%*K89*A`N#k_P2g--w%&D;Rq#pa-xm?|36ThZFwY+`N?6pMeK4K-wYF$HZY0`} zg2o}$8lWaMbXW()V5)SoZ5$cl-q86Xq8UG0y0hf-|!RtiW$f`jJzhzn7ge9$aVS7u+DAzn$8RJq3Q|Kb(l&or*j++lwZR#$0})5>MpJeECvP zgz~PgIAKs&8vlgYZ`iYR+ZjDh^I@$xv7^Xo%DhVASA!nt3qi7|CbkkbI8aUTc8x_^ z!K<&e$91rZ?A^zhU+{oV$?EDI+I3h8{51}@x1|}jIL$mY)5U%uSW}2@XXOA{)*dj4 z#y(_vOY=J8P!m<~*8ayK^uwhUJThX%(*JAfEw>9AIWp&DCM>vyQtAKD@Mnu;l5g#a zD)JxS!Z7`27Z3Y4NGQK~m94Jp*>8=0_*n8DxrfGp>UdFmkvYSaWEFlJ@(cM$;CTM> zg&`+LRstlbV;RxXeHD>g^EedYyQ_%W2lHAs8vIj?$?JXv>jJ5=#jkpiVbuwaK$dgE zHW&E6OrBWE8_Mg{m`FLPXB>L!sG}?lYqvl0JsMwE44!oQaRi1qF~Gd~o+xL7Llx0w zoco_o=5Uo%6b31$-iwQZL$#zbfc@mNB~x({wS3zs{+X_+2CjHd<=Iz3I4cB5LWs6S zKP~|)dhz*~{tKp!Pi3ieQm6IW^h=)vTsKO`uz@J2b5CZ9A^=WRqi{^NE4jPjGJOKN z-O3vqLQn|^z?A%!l;l51C_(6Bm~ zYe0B8bFpRCPY(^sFqfe201o36dI&A+%kOLNPsAOrfSoI}GHt$kZKI%DXG|MtrfFiE zow3At_(UA2!`3{_8lU#1HAw(f3}%ConUxc)Z0dy!*k-KW2Z0GXF!(+l=}qzy<51wT z^nU1$t3UK^ogk(Qz%L{(z~OqmGPun~Yw3S`bu{sVc{j%~enU#y<0`%OQ1LtTB!*Qu z7`l4jLkd4u$_tg0$hsecmsGwms_T=Ig7=IGlLDvG6WXKjn-{ zlu;m2=iEz6LBwkg{Inz<`zLxX!d3>ufJq^}AMMXq*^>;LZ@}i~8=9Zbv+HO7`9_%H z&zH&9aE(4JE(s92cV>v{9pb8}r&s5OZ!V*wUT^$Z{0_RYo*#!rWU+JKe$fax66SS4 zQsfumB`4fK+VZSKZi4x9XFHeV2h|SeM{R;tG3g~f2Wtia5L%ggw!1B-1`R6It7Env zJNbn#W5!fe(RuZ963mls;Sn3S6O#UkarufLHwAuep)72&Kk^ZZVQ$;wQ0tRm6$Dfg zWJ{b&c*N7{M}`FgM%wd?qeWt;?D?c{D-?RL*AcoB2BKf@?#6=t<~9z?OG^6Vac}9L zkp@RYFtXAEV!-W_&s{T_u^=z>MHU~P{-80nK4D9jUpQ6)9wUYdZXLZ3q5plJU=hgX zBTO;0e0sY7yD=i~$vTxj;RrEjM&4h9g1&lY4C8f!Mt!;=xL)>w8b1Fc!Y;Fy8Zeg! zI)q9DiiXi<@wW765^{Li2$5shP65g;>>9x#mQOQ)bcj1T1Ina(>tc6B+z`&Ho%A-4 z%HSnv^T>jwc2nZO_iy8{z8zCAtW6Hr2X0ja$S%wG(`Y(7cwR`x^JEU5{sV=oTadh6 zf7yzb84ZT63%En#_gTuhC}hcbygao_@b!Tr{t&wAinr^?iSXSQTr}0$RYFWEKiQa~ zlniLRwP_Sx_!81E!9+d(;+K7C@(lWQU^1>5O z!=@BX+Z49aRA#JK{>`O*ct6w!YW2fE{jA~oaDwdZ?51)%{qAmG4{xj1Xgo>TRBy1G z9IRFP@R%JhZjbV6s_m=w-Zmg&i#)~z-eIFL#H|RizdTRmr$Z>Dcg4HoZiQ(hI6K?B zUe@$CyE^>t7{Yl~t^#SF1!$?UW&6v&3adVKn?8lrEUK>iUjGvRgtw~%VysmXh<{nA zIqNjg)6WKK=$Ob7T$(5mUha!ON6GfmU^_ZCbv;Bip-dEtCeHNd5SLf~SYJ)Ppt>xE zu%|oHeV~P-q?Z{V*PT~kj*Z&XZ_8h#(`mbfx;d0VdeR>Ybm&XmXqus2MZ<7nwO%W2 zp@MM#yN*Wli*_&u`Gv0oC|n=B3*S99Ibvz{>g|mY_vaPzGJd~m8?20yrb`9UXxw43 z4iN|OgGsZr#AQg)T^3KTYk6GxPWz84A(Lv&m`vB8IBMz_fssws>E0Wug!ZTkNei(W z5a{pzi)Od;G!U951;O2~I#p)9j25i1tQl13FTd=z>PBI-ld|zMK%1Zd@~j6Fktl60DtMMwrOa& zhcbo2aZqXcfZ|97gbWU{Y>R5=qJV&%8!4f&X`VI3BGuxWEbv6u6mw(bMN)jac(prJ zq;V#7i*RojAnAnn$+o1FD42n@m4mUcsYI)*n=@AXWw=Z>@p<2@1?P5p?0w#yzOui! zyjtFd)sKGz{wj~bg?WL}1Xv3)>8q*LhozUcjNG`2%7PXHhX84bfx;t+(BuBO7;ItL zx?G-I-q&^~#I`b870|3JQeL%$nqd;3X9uR>K}^GqY6P*#Zi<^AjiLB^9WH%Ba`?)8 z+>}tJdQ{Va|7*H#O7(Tb0z}=S_;dh#UMksP5cv$+v}YO4Bu>wQB*wI}i&(%+v-(2{TSY``^2ARi!mgS2M(>*L>;#LH!vB65gXjlL z?+e3?6BEYp$PX(T!3fUz4!y8f7STgN`GfH4AGXzW$6PwT<&EX+t8h-m7!gK<7B$4E zf;tI6pcFGqzSs)X`U==;uqg9;Oh^OE%}d>ExF}WFY6KV@^QbcD_wI>9-TX=dC$;MI z;cpc(CfVab{sGrZv<7}&=zG|g!;Re2rN>SsT+(n5AnAfjulEe1y`qKgK=oq$d7y(r ztsw5a9V!j^x@98WkH=_e(MN>yu;2Mspp=q;yAU@y`l$r6g;9h8J-b-eMVKjj++P-+ zg(QiR^gSmejZZ!$14(20jB5{HXjs?BO-ZnOudShHRhC9RTW)(WMf2-`QLc)%L65)2 z5X%XF;>Nso7N1@cg=Vv$RzOVx|KWFhFy}h{oK%J-#I%EWZ+xpb$|`weD zQu+)ba(wu7A)Ar9?z=DRVyKUDzpTpnQ-7vI;th*zU<*xeVWH+<<5N!az_X=KB2HQ4 z_CV!YWky{+QAgrPbGS3h|3vT2oQC-G;jC-FNq&R`^NF!7tW)w?$}1gOHve~07`$!e zN-|VPVVe!TfWE~n4q=IcASrr& zmqk--ikQYd&970ynL4-WPOOR*i3qZtY~CX`lGBU0uh}-~&Ie=_i4f=tEs$8cxau3Z zL%Dj_JQd%dD9Ib$dIOna;)Qdzo)7ameHAzS^b$)$1k=0bPD%M0r=vx6s*u9 zN&c}z#$oJxl>$2}vQ!c1>{z-r7rr}vD@RwAlPokMmfD6A{C@o`sLO#t< zw?XL`Jt)=Bc00d9Z8tc>IWV5gytS@(ecBH?fzh(>as-6o(0MBl21uqBBUOIXrjk(L zbxL6r?m2Iko-LMqELDS*z1gJ2Ephq`^s8|x1ZUx++(~lg-BSADWJm4YA8f~TyalA< zc%0lmoZ<9l7SY(`o2Z;^gZV=U(*4kinSA-VCz^$teP3v=T2&Dr!G4^gbmD)~Bh0yV40D3O z3Dmst*b(xS_{~Po@vjGY5#G)CwKD0sO)Lf_w;|Q|JAQhZA1Xaq$V4Ez|ueG;`ShNHIvfZzNleLIAKnHKX_1e@p4lJe9B&g zU;>jok$Q)RflQfo^18zelv=0Utm|;mt#Zj3iNcD8AGdY6obCU%^i|cu$4|!~pjKMy zyh*m5v84jnZZ#Tl)vl4QoofA?{{Y;rN_nGg1>0{jS%N;J(Dv+G*Yp8N;-K6dai&Pf z!WD7I&^yWR(Z&sV`1uvxzIw1evL&xy`<|xqB*$~>7A#N6S!TXpT^G9)Kih`5DHENa z#uL<26_0%V#>|!uc9pSFqKFuYkb=Eqak}&a4B5Ts-&CVJzrgdm9&(~6#8dKGJ95_H zpPvk92}yk%?rxG|dn`d5$Kk1yno!>@rvdNq^Tn{bh^2p zw(q$a2B|nzzgg`J%)bsk%59{-6djC$!{3hX%0G|QccA~Jbm{Qx42WG6MMSBt)hO9EaizMfx}y@5$;=1jxCOsOCst`6y+46 zZAaxfkk-x;^DaX;bsVKyi;7-VaxALqm}jmvm`kEK2MX1HzVES^^4Qupy;YZwZvuyX zU~V?I{e`qq)g5O7G-Tgpl(76p(T;G8Pm&9}*6d!ZLKRXFy4JR;|6M*)jwya1NYF&Y z`is1Y`IEXzRTB4+g@I?_(kxxE4M=9~>tJ5ck!@+7Aa%lv&tD!Nb%wB$SPpqGU6)%F zLUQ3C{+LZQ$gX}$MhVtR32ujl4geg)cXvx{){Hd8;lG7}ZK{s{K}2zb_$lAi1B1d1 zhN5OrfKUPaD}JZ%(T_e(H3Jc3tYjI&+6+sfx6#YWc@fh8~q2#lWjNC|EbrR_h+;s?*sT3PzDZEe{p=w?Vq*@nDY@5 z%(_ZL6V1#s1IW`r9?F;(FvEA=HViSBU-}6SF$ZU39~v0*r|;eAb2m`boHo|uXTlKQ zc*!8f4ax|ZQ((U!5?3e}Dp`R+W6VA5t8{4W1_X_=p)S}Fe{f73iUhibo7@--%E`%R z`$u6kPJ>p?&bWxQgH<+Kk%%-+Te#e~>u!px=0KI80~Bnv#hw~9;L78s%Ql`|QQC*V z(d3#e9hXEmCr`bQ0b<7nPR*Bnxqhkq>Z(~9ubKhn!!=PpDWb~wOV@?Nq&WtUDbnpk zllM9<6!|aF^^_c)LeJHZ33%LwR^^)Qgy16S@Aa!QF?HLsO%Jqa>U4grFmukvg+D)W zqv$%2owG(-FYdy>16im1CeD|8A$cAVF;slvO-aGjEY0GQPX7vI!4$BA#M7%J7UsEC zrHuDJ42KEd+e=ee*=Rw6pL);UdZSpnb?y&q6CENQ)v3i(37F?0FB>v=pBe?IY8&QB zU}Xv!d)n)w4YNxY(o{c;DPZj!AGR?hxv=Cl?a4FqaSB_ywab@Gxy*+UrnmAjp3MSC z?DIuKV@@9sBHo#yS)>dVN_3SO1sVudEPvSfKpnxtGky${_=jdj9+Y#pPSUxorR|ti zIo7)$4Wmq=DHV%kcLy)LM0F!&g2YEgrBMul>44oAHU|!Yb%6q~mfsJ5!Y}lao`4{6 zOC-J(`&d-e2)!o_SiTowTG&ACW*THasTN5?W}q*O37TZA25Bi|fdJIz*=HRlL>9tH z3ygFm5GINyI^`RZGW{lYmhXwAU6ZE6AR+!E8Nakc+_3KVxFbRo5t(?CsB~Slzo(g^ z=g_kr?6FPcRSW>!>{;P-xi5zEc5zb_+=`xD@3P7afj)x7f^@BtHjktn-}8|=(RUvl z4*f|@*+b{6S2nB1<$B2G{iSQ?TFIwYOqEG28h%=QDhS5(tY zhl`2(8GZo-nHT?RoqZs;C|a->6}QgxlsO0CFGbO{9#`p6t8#UEX^0W*eBc{I(ZMB7CMFOz`Ez;E+0SVq*paPnSn| zEwg2pMtDbZ&lcePQbw3k<$S?`8d*YR{wqWRe0RVgjKp(vOk%96Bu^Z^;43%dYeV=! zg2BBGCaz0>AEqVYefox)u9xOsVlIfw_3BJ&lrQ>NTvw_obnBXY9Br!k-FPCs6a^*q z`Y6|u*(08c_SmX@&fsB2P`)UgkG%|tzXQu6#aYmkxy>h8v|h>$djHlWgcm0^Vl-G@NktKH3k#SSKZc)mXbS(wz>aF zET70^!$d1&9-9sw1mpgD|BX6veHbIX=_y}j2A{_ZWRn^0YJa@4OsmLc#b}^*Dro+Y4wkkvxAnUx}7NL7Cn31Bv*;30jwNGkL zJ7%@r{7i@vpKy%PqGf#DlT}(Na6|p7_4U^KOGSDR-!G#4A}gYuJEBDVVuUElKO!MQ z_BF_Lk4u)XVI{RLQF@%5lO|%5%e}`ujRcfAdhEC9?wYGziJw$^><+`M z4=BGfuhM_M86Ez=7F%Xcjx?-ZFwwNb39xuj^ECHKFhyWJPL-}+>%cH`T#U7GjO}RV z(yQ?v8FH$~#j$hLOhSvWb7s?yk1v8pCjKn2ewyNXYZrp3_Iop%5RmcMT_&;Ot_p6>HGUHKIO!_>wW8b zX)`CPLQr6^oDQ!hWF(#A#_@tUBigx&+-5v$2rrd(XBW-Yzt<#D6PKtfx0CkpJ3^$P zOm96Aj(DP>7(*C2l8Sa=?Hw3^&PC$^w?|+NLie0J1ldVVi42|QwKm1Gxb!1aj*!lia#}#-Do+)?=e9r zu2+d*H~)pFiTt7VKMWb z1LX&clG4FYVD7=5cm!RTckP-lOJ+#92Z1AmI{O**`@6QNG^E_juh#8Y{g2{vW2xa< zGE%^PSCh?sS$Wn*!n54;W@5KaLid?dhfq3O&)S3q(a{P&ymt{q9M-z}_h=yf1C?1&Q=MuCfIq)QHmYzEC@X^=YfEV+wl@BeQ|m?nKe-ut_2_n zBr=>FB7Rkv!$fN+LL?QvHHy{l%!!bW7!6d@OS@?t{)m%Ac!}yShY$)QIt$-H^$0a= zOSpV{DT!G_eOzGZnw~|iP(<(epbb7jUEl?1D8{A)ZUHRQps>ID@n)R5NO^+6$f7tJ zQo*~i@858knoYe#MaM||@|~Y2KfD0VdT6rgpCnDHgf9#EDg!2MdTG9p?Q~|K7;{xb zol#X$3d)M;@rG`01kaj=k0J$kuW0hdBVZ}wj>lq#e`!`#2RA_RG8#9Ec_^#S}e zch_Z;q-Xu_Mt|bnwz81Eh6dXnLQNT{@r}!S$L-=uH7K=O!c{km@zfZGDlP!s`Jm~# z%&d(**kmqpW$J^S8_8hTMhkFxVLh5zn?brr>R-ALH`SQGN7~2^CTkXovQ0XrHC`b= z+X{kBLX&Hk)%$?tHUGM#;E^mR#p=kQKF+WK!N(QUF5BxdyX&SEeV(5ufSwPMPJHCh z!-&7p*TSaU>pD4IQ!>$ku{7X$Y2kfzQ7&7eQg2xwycLx_u!%z|R<5vWOwghE*KFK3 z?W$rhd5qH2xn9#H6R{|Z;Sel)vbaVSL_b)vG-8Whm{Sv*7}WXY#<{f<$~JR_-lBhG z_GCDoUqwm%tPKWslq<7>0sJVNGTyH@c}^T!n#Nx2ln&RJUCu#12o+f7@3ZCX^S-dh z=o@x@*iy5>n^sS{ztlD9%C<4fa`iF~4u5dXn*B4p?<|90!8h)ieT9uY8`b@gm@Q+$ zNQ>7q8FXH)m2hFiOFptMAR1t0*@`OyPobsVK~76qQMxq3TbpAA~q>lB{Sd zh3kHI(GGMHi&lc^7y&9GF0=TjD$ zBmNXE_Pt5Uj)X0i$k8qBsk*8&s>_Mb9n-Wpnjp~*FRAwf$Xy7g-WJTlEcj0Fap{C` z(9|H?9{epW1RWjkN40vkW4+_ZBK#gN$X_*4&D}dw2Uq=hP(Tf1mgnn~pj#`-lweB; zQjZx7bn$#{pvUYFcuXy6t6A_81wBvfInN2mRVDrD_$Pm3vZvLH_t=Pa;(5Nlnwvz8 zGLxfi6ReJd)T?paBoCIdPnOMz)p8^u!()sB*q3%XwT@&mC3C$g_M%Kv> zhCvUB3*($KMM8O1i^7~%KmWY(lB5G1$VyR*?ZSBJVi7+t5`wmbjALD_lX2e*R4K5Q zJ`}*o0THsBB@#;4MA0weSDm*|%wub3z5CWstYMZ{ipNhKHp36=Ew^*BZRAuVJl6S+ z(7gAMJdZCOfMc-)Dwz*g|MZ?*IJ>J0-m;bbwZSj}A1ge;!?e4MP5jR|QM$|g zn_MzQL$WW+;T5Tn*JWv?>Yq-h>l~=RM`+6A760>8oG7Q3V>BO!;~KBH2ml+m7}0-@ zF}qo}K45-1F@9-FXUrw@)GLaXnJgIQqW}K)7DqbV5Qa;NGQXbkprWyiAJ(I{!vb*Q zW$9r8>!C8PY%QtP)Wk1}vZtg~zld&+#2UL0snv(JKCgUpgAb*qpM>6yvODum2)bY% zI$y~dgxwK{v2Q9kZBLTB0q3(7&rC0?$*#S{`a3bnr$zK1K(6NEOD%<;;L?lRo|)=U z9DRnN#MIEyfe&tM@DImZiw85gr$gjw%>>3Afq1!QKm9aSZ-LNM+3DhpZl(KB9d}0T zs((?|17fi{3|9N%5m27N%kdX1Ly8nHz$bJa{m8`sG-9P?HiE&ybN%loES7%?F=_mt zLPS~y0|50r{SWwDY@_!MRZ*IuZC>@LD06+^x81Ocw3_vxMD&8PNFX26F{qO4Pay}A zpYO}$K?*U)01o-ybyRl?bGg)DbgZ#}p5NUEJm+*lrUAOj z9oM|e#c$4sX**8C&N87RsMLCgL+-s`+^?9lhnPI^1nEq+yBvHLQAc=rG4PM$DFpq7 z(BE^NH;a^*HPh#YzmieEd93=bwKFe=WAJ=;tk>NdhBX~bv~BjSzy1}i;N#+b_PZz; zpAUF*SQ4F5Fq}QHZ?0HaM8>amObOj;%re!HW?p{_YGzSvGa^G;(ADnNWA7Xu&c=hS zcVNQGX2OX|v``zP5;PT^qtiUK9lZ}#81>{aBRn5($f7}bIP+?}ZC7!iNC5HJYCNOb zO~j-8nQo%X$azt#{X85(sdCalltgDIeG6oesW}U_thG=?gJJbDeYTp`N);E&*1Hk8 zZ}Y@Fu3vT>>FG^=LM2Ryz)V3hvofVQ^eDlBAm*W*>+9+9b-&wjxU?Vcz6hA#@4hr& z<}m`#aQqD2xxP*}x3g2u!KjZM1hk-JLD$l)Au!6h=&z4k%tRojILMUx&mi+=9Dw|A z>}Qid-hpvYsH0nK`<0B0Md9~iSS$VH-vK#ev{odC--l~Yq*-N*B;wu~Kt{D3Gz&R7 z*>t=43A7eA{z!pVeRBli^ypX(!&i`Vg|HLEI;3y0%-w0)WN@p{1rTJ#S&^yiC?`I@ z1&#_kfuZ*Z#~0;>Qu=d)e+tobwgc8}CC7F!24;}F2ik}>1D-4nMsfuqYQsNP7P1E2 zE>I`@>nO4vk-ohV3Jl<4fR)@t1UU84ig;~8V5kaGjqZum+q9uzgW+V#a3CT0{WPE- zmuN^B zc&uodNBF>DM>VF)uxWw6kt5~HkPFjotZ8raj^)~wL#BkONU;xFTFe_p{U{%+EFbeWq*B{`Xf0VK0jOQz5h8Yow z;0#EOKOQ(Nu?{W0Nmo4KTawy`!e5=;Qz=W*;+sYb_l}RSWSjm$LZsuX^t0bDO$tE; z>q0gTq8*R$A&%B}tPGeWaB^~G_oCY=ku=Tk`F?JY9k9=B=S3d`l@5RMm5q>G+ng65 z7#9Sp>_uzT$9)fE2J{5P2Tss7Z(ixuXzAZG!$+x{V)zHn$zq`}J3vr^g}bTXclJyV z?LO@-MQ3$|B;#0#PG_&KDj%$ue`iwm#-}nPFSHJ8NH@{&TmXEx?q_7x40)nW@rsme zE0iCWxhbt)KO02F5Eqf_upseB$MEd0n1eo^ijQ9v-Y#BA|3GQ5t~`0*5v9?0`N3$1 z#uv+G(zg3~h_O#{cOO=B7hT4YyZwHFotKl9h+kDTolJUc*W&InCKV$V6SuuUL!3bu)}(nFEJl{LSy zwL+)e#rT9_Hn$9CMR7(uASVTg0@dWUBw&Pu(nCx;Y4IUq$@i6`{JCjlm0l)#V14#= ze*E}&sNXFlF>Y0vWB<)H{df6zpR9>6PF;g#E*=M72mtG*(s(byAxA&ZCZyX!o;ngU z%5?+Kx+;Uw$6>qXm9Jg%wUT9~r4l>7uce#LIE7js53^083(NOgR^}cH>-MZN_wrm8 zVnCc3!;pGNVnI}JBPv-Lo8d6 zbv!tBxUtm38K}vSwrfd%^jO}%b;#>Q7ax))Srm`eLj%Tu6eDr9yzFhB5Cu!-WX-lY z_ScJW!QbD~+OG|o-)Ao=H*-7N;TwZEbF$go0Ucr2ZWO$klc6`SfVUAt4z=u2$WRobU}pHmmr6}0B|$(VMGI}J3nNc;P1Sc1Ap z!JQ0r)1_c5oZLk#WT|U<%FHpyJ>Ce2gi}9`6#QsF>F;7OJ3M1HyA%$HDP%b`kt#4aLEm?~gdD4CFTzuyVA)z%oWAYr^_1=meJeFO z9!<1e5>-~{AADmzvS6#oRcg5;i_FOu!fmYH8eol$tflhT5OE!NbUbXP1EF%m5Fe*% zI6Yins5YoX9U*;OT^2eDlnl)oVA)PA1<)-vX7Qk1>0f($VT> ztdy3D>U{h56pOvxEv6&f@^c(Ca~8&q6p0C;cUCzl^Ed^1YHUSJRL~2d>+L z73S-Vf+rk3_ih^57aT~>ee4)_1lhJZ2Ke`hiIzem};=T9g!U%U|eG|Dw&RwIA7 z1ttUqEFrlUjKjD8;ZBLgZ%bA8M)YwAberKet5Y&6lJ}VI_R(7mT*jF7Gg}t;*{4q2 z;yXk$rSXJ^Dz#QQLTlvd(9(oU_}mkvgdNL-mMGRPwEU{^23Z18Ez> zByV`CP+!oA^iW334mpDVrfBS5m0ns%Q&7~Pug9@Nr~%6!rKTo_l3%1(hPjksZd@c= z+V9Y5s52&f{9*845&^CuYS58zNd_0_`ryNT+f=7X-O|$C`LUfP8ZQ>3eXd8|fwV&O z(%L`bi90^#{Dx#z>yO?+J^iofvm(%isiJ|YT;fjc>8)Zd7>Dn7Mzk`P%WA6^o`eUw ze%i|a8kCyIhVI+75*j4Ca)eA&wEid$PmK60!Q)8X)Jbv&#sMcAJIp@*G2(6CJ8zh* zu4nouZipOk9t_iRHc?=X>lxW<@)mZ^;H=Cj;?{T?lqgzA>vVnWZi&WL#w)G4INs+r zpEZk;Ts2PwWmt!-UsslrAgyD0AmKlO0zlu>jxf@cG!AZDj`V8Erd=SNWmmHQd?fl%5kPokDI}b;bj8u_c)v3_6m&!RC5Ou(P?L2~`z>t26t2zH zp@XfJVx5z@ix3qi3)=RXgFKqf592=5c)F&%D{^KsWyj;tkP13)HTc44rh&0gPGwJT z?aYu)u#%AHx1If~s|&SiONKreKfYRkk$JQv=?CC=4c)R?+=}emNj}rxN8wY`hwFo< zX&SkgdSZ{EHH&Zp&i+#*gdHch-ES?V^fo1#*V)6)GSXQ@p)-6?!*svg4O4Ch4|@cM zH;UDL(%$txp-wg?06dyIGpoz4*M4wmd~Z}lxnMCy_5ma*-F?vrx4k1aWPq76x5=%6 z&=5d~vW%d@r%aU}Zj164)-vZS=Lk(ZM1PBvO4blRA%%bn(F#LtCN2pujWlD+>mvgTnj+I{ITB2((;RMKB_N}7nH;t(3ba!8_aPIG8*Xqw>ZS@(<)kl!l0h|E}c=edZL)pOtD z%`mxk_1ePe%vObS24TV_--9#+lE4cy?r0TIe{N`{+W{_4Lz!Ol@XzV{b$Ha#nhAWt zV-Tp&@WM1We-VeP?ETW!oPt;!?^sH!j~WLi-t6?J82obUR|fSz1ZuWELAn`$>@UN| zLnjSOEqEdvw8ngg^?r~y5a3z}vCG%}{ZT zd$WS>6%!_KkdmXiA1>A@`^!&k4p?s#tANvuBe0TQbihcf6fr}j=_0yxMkX7Q{z-TN z8$`gcWNT|ZC4T@7w7e&=&z|8PQ=;8n^(p3?e;4(%Ae9N`lOpmXx{d<7(I5&fA{_5` zOIzI4to5lQ2|Ag=G#O-J!hgW|ja5#~*zeF9Gt|f6KwCG!Q(8 z2v-+B=ebOOW2B^h^i73>s0kELpe`5GSFYEfQ_1K3jw?h7>s*TPL1-zBi>0jSwycEf z^`2C|w@4wQxH}@zP=KbkOBTYRLh_=3ug0mG)F+CXabh}qp5TL9)L24ZmKcFEvOr)d zKzunkYS5bhu}xKVk#Jn>1DqPnhsDw?jTA=r!d`E>t^B^n%qDzAd)_eUxjbdUWMfIo z(Dw!D3O5H`h=R0B;WI}$)eu%F^+x-XSa zHKx3;-aL8QUTV3Go|6G7s) zf(91WV;aT~r26iU+BL?vZQSPGQ!suAVY9YOwExGF_upK277o_`ABD#GUvvBavG)Co z0u{OfqXM{*`UDXmr~Q8Jpy3(w)~A9NqC~K#qeCc?6pwu1r!$f4_sza-<@(15+$R5s zHe*4*w%KBju2ri)dm&(|B}V`&_>)d{Y=I?|`s(vk^>IZVw;0u7e{YAC zrR%#`G9{*7fOsy`6O0=&jru!qt@^^{Fq~Ojy+wM{e9xbP8Kd3pqVBH_YDr`l@%479bpA<4lgSAN*W<#Hin+$)Gq&6 zslR>5G8G03<6o_f57t=yOm1|1&|&XwIQ&Kx5r4guW%d(o=)kHfy4$1$;-s3CvQ8S0 z?Rsu)%`O3Lw77#u#)6C;bIF{!-Dv<6k0pB$m$|QM@fv$d7^ooVa##C(6{IdIMQFRZ z@u4y=r^w$V<~!n^6O^iPxvRRFy5?*iiC#`Wyg=wPQw7((jxP6T`gLPtIVvD22=)~H4RttD$*4uD=)>@Kq?12 zj|jtfV^7KiiVbbNG(E!wKn~}e6H4d@|6~UJEY0v#9egTSE4) z3K)4}v9w0yD2H{VvnKiCPcei{Rx|KLFR{fOk;2XJjx<%s?UO<@YtB>yZ)na_vo95V<5 z9>5|(@GuqYFst-GH55BRaCduoc4bB>BbfPOQRVwH7{?w-Oun@YP5^6|{4mz>hNa8Q zxsqs;RlEi^x>oC-hv`pf`vXB0)v-w4XOe7aBVgE@RS`2pwj3s0fCIV+d5br^pxiapVEkJk z-(Snq@0;uiLXdIGdE-Tf4OhZE*VY|zsdRAweL!Y9QjKqBmzX+~msIO_0vq3aH`T~k89+PQb4|jkTKK^124>L5(4O4!qN#j|ZitgnHMT-#|cWeg2aFh@g@-G2W-DBkf zlp5|ddG05UDWfw8W;L>i>#rDR-d1naqs!Z=Bc1sY)FUWbf-9Rsmq#YXq+PIPtb^vc z1=CO>g|lV2;5t@{4EuUxtvrUOZ~$QfQLDayg&wu8X!;blQ*c0S3bhU&=Bx705sr@C zb26-_yx~W3pQzDJh#l!RYhr+57)<7{QdoNUdackawyBA257nwirdT`Z^jH9_zTgI9 zWH`TTonsi?<3ax`kq3#2)+9{Iu{MW6`Q!3{9h6penpL`dY+0!0O=T!527td^YK`U^ zD}ehv<#=u=T$zVwVk)3qQqT-$)Z4K)_TxmJ7fYV6H@fY(42Bi{Q!YrIN zTn&9$vA<#EU*qmUljvE?On{U>i(#0+w~j9+qP=ny#g9@c1XIqhe5Uq)v2{+-m4w~a zj&0lS*tTuk9oxx{ZQJVDcG9tJ+eSx!&Ogp~ZqB)>t9o};jZu5NtLB>PnT3BGW(w4R zt5sR~$V6QaxY6Nb!DXLJ`bCuXU%_05qAyRz$k986i!;(_fDgJYTCM9*RO)f8QCzZ- zgL;O`0ztKR&qiSpG7ZqO4UY{r4;ds!QLDLD{LPTSN@~Fard^H|(aya9D3f;-vwCG( zPBmvZiga*b#~tn9|8n@>qTwD*Slwr&Bz+q16`21>>-)?*2Z5!WeOQEs_Me&T?XnCI zM_j%&_fZU`1>$U7bgbyuJrdEVO7s08;Hu6wfIurGbI8o4t7Nc$sv%^q{_a((Y(1MM z5{~%7W;JB=;-ZyLGpR=e=$aJR8mWjSdX?Vno`Xw0P_%HNhy$l?ze3pO_XP!kR*ueO zo;_}A{Y`EdKO@#YNUMtLH{f{EKp@b4wr!VVU|0T^7RS)CHlf-MTL2;Vv`DMMJ{|RA z0FG7ABsV|B!j+az+{Q4v-;O~6MfnAr zo5cygNE7ugC$RBQcx$Y3{wW4*WTAQ$xiST{eT(>)_sr%PxrRIgqA%4Wks&9qGyTrn zG}j;^Z1gBdR^B(mvjyQaKW(@kEa0!--P8T$IsRM}oLQoDkEY%9CakFtn0O>T+QEAnyl<$(a!Jvb>8{o$FkqahzTUF34cU{5;9LPCSx4?*pHKG zgotY@oUHBs*u(8iASo1GeZAk}5Xe*$N16(Tsr`2G{anud%QT+}-P_~h6?@fTnoQKc zwx39&>5AKGrlH-AwHFOZdR@6SO#@MzRM$3j@ic7jDHz|hT2AJho~Oe_j_uE%YIT4>PCIL78B{4$vxU8c#^o`@ORX4)08z4rwX#5-Fo z&6jR+*fy!SBC^jGq`hLeKgPnWay%jX34*vRyiqZ7HX+*UUKxk|aosT3Kr+JOriSZw z+AE68DLXkCkGES)Q{dAS@dL8<&`%Y6t~)NM$H{m7%g@6@O(} z69Fim3G=%SK(!tw64wG~f(a=LdR2G53CagYXxlhZ^L_X*QK`0{zKYs&tUF9n)5cEz)7 zZuK?w@Hw&?K7aLNeNRDy)76)9pMN(E>8b3Cg7T(s(u5Y_x6A8wm4z>eT4V zb}KEZ3GlJ>YU-h3%8NOGN67jZJZ+pk*Q}*2EXBQDYj%7j3Ia1JLKRS>=Pb#O(QUHKwkxEI&=TSgdf^VpjwMNP@C=6u=j!x;cz(v>1g|iqoS50-@yLzsAc* zEjaO()xN2+rea2Br`lnQl_U=w>1|8t+XD!}cCz}EuQIqS^;%lPOaPr6OArlXsl*72 z10WACM>zt*=AbstYF&hGj|W zje>z<6OJA?vCzykSLPPD92Rh_Sn6<`6N+KlSljkSHzxSi(ZCUL6U+$Ir}~FNU^`w- zS19>15XS)sFBd-sLH4SDPC%UIj;7D5;%IQHj#a#P8$pnTD2`PC8}2ZX#&Hi`8aPvs zk$@^7kC&8-*M4>imxiCb#nNX_lR%0vPZMh_xClYA{>%G<2bgm*3b?`JWir^P5P0rD zex83uup*kXA|zN-BF{Zv&X{}gtMl(5g#k~bn}Wutob)`K{?h4Uk35@wnWmf`Hpkq= z?k59OhLHg$ckDZWKD20``3kbfp}qOd{%r2eG$jz}VZ$qDj(ufGc)W#c52!jM?brdB z1CCu7%4fHyDM9^Q#sIa?k-lQgn%Tl%6q!Y+)9M=Mp!9 zfBbCmcFnrRmvJ!g&AH1P^E|Q@K6(Axrg{iub2154yKDWZsJM!{3&9C?9B;SNpE8Jd z>6Np7e!0OGE5K@s_e-B)$_S;t-YUEYtRz%2Dg0F^uWfX6PgMYH{4dE;YhssCumerO z`-h~trlTLj-3TkFOTRimP?A5-pAB;5A$>Klso3EsA-Fh3y-k%j13+(-W&<@spvozh4)I%^k>;afNgBq4+X=;KS6B zI!6dF8zuA>8+_^%3q?#oyb;R$ukcg^x`?UMJj$$n;!{50pezOw)2U`&B3YD=7J()V zJJI@s1DeP@w+Hd@O2iT`e@yW}9$}nha*VA0y@Kyq2uel`RFz8l1_fRv-k^sE=hOc~{%T}lRIDC5dQ@+?J-O81zOoZg4NI&!ph-5kb})R}7d~nbfe=8&XB*KD z@=T7T95hUer7p|Vb|!#qX;-#u$mRsKK$FDFJphdMAzzaDNTePrs8x~kR%6}em{`tQ z;>)RCo!7&PWZ02_Xpz_-R%eH6Oh+1($IapdBEQYqBu5mYnzb@g2$$C>`Y#jpO(Y)R z!sdF(M=1=jl|BsTJCFAaVjwSSv&=1#rzmB~kKlu;WwC5P(t*d?)ed^BHh*@W*z=v+iqvu7Xa_D|zJ5>|h8GH9e=+#jz8g5!FGm*6m^628 zFhrQmdz(iV-3s+iuuqE;$jR6d08S$b7wG@rbsFb?g8!IVnK;uJZ~v=K`!9C#=nsn_ zJ}#Y8aG9O9qW02`3|H_ON6VB^I5RitGv!BatsDQPPr6bo24G5~@kD~hJ4|>|*4!yIYHe;U77#EU zJ=T;?P0w6pAyJt#k_<4X^>%vP!7pVoPY*1M#o&oE*dWiqCiNglectKv#3ewB9;^Fz zehb-}ZV^1(eDZFu-=S91po@Zjzy;qd(wcXMgs9j1y{#eU0( zyr)I}$rAdKw`K-%U3_GdMy=_pFn!^=!3DbO7THkOZ@#5|ashBM5gB3NDeN)QvyktK8@`QR%&X_JbR(IiR~^q+k)6yK+bmYaeAzy4&Me^15z;xKt#O7-0$>K~Fnz zRdJnAbI3DQ-IGXb_7)2CWfgw!fVU=*IFPS&o!e|9at6GLp7ZD1wQd@q5}1dYYZiFySw~?`e#siH21vecH zoCaP%+l3TZmp-CRl7fx1 zDDc-wbQE8jF=-{r0aqR_Q@@37)(sWSYZb( z51n`rA0iB21tmLjU5 z8YfO89(!`ME$9XH7S+&N7B_KM=|zcC6*CYm*Gc}QJG&A6iG7_h@Poi;j{@@eu)9t$ z1b}AO2fcq6iv)B^bP`T*9xL`ny~vlN0(hL(+EvZ>V!5Z6b7k>@c*TWd{}hy8Mn#Z{ zyz8hLn1Cw>x)9ZXG-L|x3tSv*R6`NyAI-kti2*~J$~v!jXt$rBQ=6-);q0cxM{yIX z@*gltPXdOEU-w4}c{#0N*PA6*MPh%%G9;FWD~SY;<)Dd(`2~=0x6de!Nt2{62jIyP zlM#X~Y2u7*v^wMn9`^AmBDQu5d(`3$EcXm+B3C9HAx!TNCq~RP7HMnffftg)AcH8U zKM}iWv7Q8Q3aPNDUTigJLNZXr=!XM?HI>cp{E{abnFi9c8-*$sOnJj9W?w-rw#a(g zysz#|0wPe++_QsqT6%kzN!mpB1(5uFm;X@K;3Plkbc1Hm!!O1*YJ8s=sVtBgE8}^U z_f=HP>Yyp>ba#%57v_K!=XI)Nf^jE-{5avYoFcVCQho0#=Eb5kr*#gR~HT*H{ zY2&%$nYTj0AZtm&&@!>>GD(u$_!H7GLM)Tt^Yaly^Tpbz(4Hag;~h zg1FhWgM7i8sKLlJS22T0xO<-2w3T1o!ydC$Z{@gZH7Zf0V;}I)WKVUJMc>UO%S%>K z$mh)E;vj=fs-s2sme8-n02t%g1)9?c+=rs6naMo=XpPWCqrW9Alu~~MN*S=GRO1HR z_X*IOp&XT{gBSl=xnrx`+5qDHn*bgd3bq8C9}(r82P3apXw`0YZbAP)` z7=F?$KP6MeFjMh`lLP5fhJQKih9G~03eZZzWEfum)Ad_~8F)^VMMW9w()4&~iFuL< zuU?v87|STUF7HL;3a|(E=S>U_LhhA8__sfu?OK$h^CpmQ?;#ccMBg}&Xo~S6xG+#Q ziX=H9r5!hZcDNm@jn@+`!5isZ#UdnVZ=VTO2aeAsc<12;kUc zZKi^*1Vt>P2f5Ll%r}@!{dvS&4RLk|90et^wWTg60o8CL)0;Z3Q6_(w*SXOe&a=3e zQSi$pIKyJ`V3#Q1*XwykRorKB`9-FdUJ&y3#CgyDZr^IH6&$6S25pn|0$yz-V5H8T zLudZTQ{466pY1gU>@)KDsOPcx922Se#qF`o$c3*F{_HkzdA+Wh`?p*nN0o?qDOiYk zTKr7IfHO7!ZLF|JNccSOzm*(5sm7ZNO3X|?6gIp**J>G3q=f7~&+y?m!~qv)V~u1R zO}q{o6){BM`4~~WXWg7WEseEjdo2Fa(P2G7(E2~#G>Xuf)|lRw9y=kSGDh=%-1axW z71<*Vt1yl#2xLZU2n3+JeEIyC=@Crt7B4FI0fpI$7k|`R4FdDa2i9wD0kHUP=)W{= zg(r9x2Uar>o*5XeM+Ge*9GPuobFbg()&&T&`tv_)^EnteqMSaa1=Kknj*lxQQomgo zMifXXls9IrK{dph`TaiXYcQ0GahX5n#XWeho!HTh#osBumd!~!_V~yTF;`rvel2iK z10n>?i)Y+Y(3d=M=-xa>$HY7za*w~TZF?>I!a$Rf&Pn}xa0ySfx@nGs_?+I|;i|s< zuNS7)ybAzto%VG=q{(--Cp1KV4mTTq=gRG}x>)&;v&CLwg;Wtkh z;wt&(tt$-JHhq#LUk!P^F=OHd3!aV)F6Xo^oGj-WDOh_r9h+)q6Chi7;ocBWxRQIl7XR??R zu@)(WS|2B$(d|rH4o2cbQ5_=(=Gzst9fQx=&|o+IlxB^HuR2fPhIlZ6I}w+J0K(p0 zL3R{4kvmfUU2+y*-k~BodLu7QG@jdBmYBQ-WaFC{?kD$uz@g{60ocWWu?$Q&u{47{ z<;@d$u4fi4`pN7p32A<}iIRJSz-eNUxI(_Y-eCkyBX$zs)Iw9d>16K*JHT)Mn|L{R z?cwx!`FDD_q_9A4_WFfgq5u8>0OQDHXir=F_cJ%j#mtfR`tPSC4^ftjTVO=%I?*^3 z@3hhDJ+XJBxs=93O15iL6DH0o2`K)(fVK*VyZV{FZ4%}Z#hJ#Q=yU^-Lwc!MIq3Cs282@{yN;ND3(yGO9(R7A;gsQAo=-5~j|)VH-#WhPP07 z%TnBIGo-G4jw6EuNOc3?5P^mQBqQ<-L0;pzCi#Dd&>BX?x#xz1C5I3FJ-_ZRfP=y* zFn&urx=(u9Pqv&A?Q2xY3+=vi4jo3awKXrNJ&$<6yC!V)I?vKvR&|)xMo|r1-yL&Gwjek2q>`Br1c4@E$0K!s!3mr@z<@HQNZ6n$? z8)-T$#aVE%aj;}7j?KCS5!j8FuJYAViZyQ}Z>{7VH5UCgxk3MBk8d0f5{Z=myb9pq z--^ufHDxzEqo3MQr$*ac&*|B}IiBM-0OdY&%+vN$`x_oYm!kDry!? z3?Y=c2Pn}qkhK`CHQ)E38cDOf@42k#dWKaBJ||wjkkY{L)C*ISVyUXIAK4Gw2~jmje3zSlME-6m{fA+G*088*A@DJ`Bg204L7XGc!LE@%{x;YXt6; z_6rIW7nGHQGff%_RHW7U7DNLE@ygGmGyT(J@9PVGHXJ86jfnsh74APBcxLvWd?r(T zP?0pAcMw0|oYsza5L-B~19ga(|2pxOVZfU=pCA91BFy_UctNn zx*s(v>6f{Pp0)U@@ao*c`R?-kdtkHib;O40?Ro$5uQxSiOGBnLS9=@R17Tf6vl=O- z_~vl_; zVKKZ5NS~qean0$0qKVp_E}mYWNP#YonM|KbZ4E$n#%p!`>$Ga$xvB}Jiruc<%f!1K zpG%hA*>MoK69#76RvWaIT2x2G%r*DRtg0+K3Ge0B2z=LyCbq$)T_^GA^gTuFSjv4= z^OGb4V=mI&hCuQ&=pbVycudi!jIO+kS&U^eu0#M4E(>zXp6k?SrP!IO7xUE4KYJfo zeMLZXgmsFXg~6p#ifgiiNQT)m<@;gPO^gv&}2h zLxvs=kI%Q=m40goc{u?rw|3Yuo{jkbj_3fMzR5>wJkC+6DG4M!?{kQif-jfJYqj%! zQ+Mck`t-}Mk4t|Kzkxb}N2>l*WkR<$3&mJhx`6vZo<3i_twlX>Bwf{AOzZmy7+ElU zMSlN#-jaDe_?Stmoz~Ckbo_bYmz9DA?Zir~LmvEzxshn?PRI5_&98jE1p0SHf6zwB zEP?`cZPeBzJ+#XLg}Hus>+dojd5jU&v#*1A+qt+(5^p~!Q;eCS0k{a;*3HM(iD_!R zzyK?ZX8ulVzI98%Np5~$2%OkKD4D@W84l9gN(fyl-k-0^iL!57C&5XfpO+4q#&k-<@g z6|LNoeI8_|S~SS)5&7t@6cT(I{Eh)gS101N964Kn_c3o*V7Qh80qjiCgKnUU#lx2C zs~kHK(ftQwziJ<)_U-1ui6QA8Zuq!iHq(0Ha8L`Y#^F4@O`z>6=ktl}2`GTLC;fSm zKBt+nj>8Tf8oUWVM41Iu&d9<4SKfRrS%w6}5OgfFT=amz7Ly8?HIC zPf@+UCI?%(4y0fAmYvv;$kq{9KC^;}7UA3O6!WTU2LfFZo9V(?GY{j?7ZW(wMFg&F z!zPFx!6$&}5Pcgr_~jP1R|pW#lN7o6rxz!2Yq3h+6nLu0IT54I()wV1d9AP?qN$-s zjg%f)&}IR}$fMw@=ZE(}cING0RvF@r{V2CF1pPT50563P?$oF=-STO5mP*BSnntCB z+g&^KNtgP3=RO1f^glLIq9FZ z7O}7G&cXsmqph)R(}Is8;&h;LH7uNkrtJR5v04E$N>Z@89wD92*@J?|G3z4V1qRG-%b@wH*vxmG6(~fb2u< zc}|7J`R`Id*{b#O`{atOy_qU*eq zPA1}SFB2WbNkp*#qWN^~bQO@A4JfWM+_GaQ*fX?mAbxM-MtifuCI3YwbaT)2fpSxqPXJ=>&h?-Cb?Y=P>!+`z7 z=ID&Rj%ZfirvtG5xKRW1s-qJ*V9$31%w;yLt^ai22kssR2Q2K%Hyj$AQ7D!EMlMO!0A^e4W+Hi|(P{_bBn9|UX1G0Bxr)-9rifsunC5a>1^vhkFAbRDD1MF;xV$ zNPLOd5CE`{3azFuBJQY(NN6l%=SqGYIu-9^#J2woTJ*}9`gOJAWUUX_W{PD7%5G0` z0l!E62x?6kp|i}+vcga1MQ;p-iz7=ee<9^F4d;0+n#|}nxI1Ak7~@eA zy$*&rk!*1>bRXv)o^!f9M$A%H-!T7Y|5_v7#Gqy6e($&AH*G#lj^L-a2Ge-QVBy5{{^5E}c7MwN0GaLuBQnfkn@*{#7h0r`una~yI^^dXlN2m$zM z*NGWTZ>3F)sPv>g2}nm+l}gGtLdM#lLhQUq+j```Wg$oH#;zHhXi=JDW}nNy)fGp1 zM%XIt-3HJ5J^Oe6^h)sPmk{}VoIYShGd`m8bXiAx-H4BNL&R89^w>XF9(0$Q@+!YI z*?^0s)Cf}*O-rIdTp4gm-_XeQ@DmbmvX^D+R6IJJ@3 zi@n%XOPbK!aX2BLalBa`jxN7_aoy(mt>N7aw_aZf?6sN;C%CVat4i7I;TqdM z)L_g5xUBH*dRb^?6KO_-CyE-O&uR0R?~wdgo?p8*c}lx`7E)ZFDX?%8c@~|R)~t$y zVu&~Cz86eSJ5?#vdGGu*D6;(m$( z3}*w2nZEb1iUtxTL=4iCF$u0Xc^f!v2LuefDriWJ`~dMCluspuhgZxh2}{NsbNU{r z(@3118#iBsEmu>zzCs=%-0{$zrB5lr@Ra}RpXwn{Au6C9+9HQh*y7XLbFTa-Y#p=r$$wx$} zq!S^mrBo=7q>=J?6RTNc4>xV9BaiPWIWv3gU?Dxk?o*u%=`Q)c6*lBn%mfh51KER3t1&8S|0&yy+;p#rgNq5Z+O*cv zH?b-7CzzA+#RtTeuRyuDqHj0RYm0(VZCgZ*GBGI;#W0=d{X-Srn$QccV}+bP@~M(+ zQxFCr)S1!|twJCLLij6Xk~2igh)Pzx_(2G4Mog0FZYYj;F#!O-qQ@J=VVtLB1S(V@ zovu_u8sN-#V*x;#!m|=|0?7{FT?6E&ONRaJtURM@+u`n_W6c;eGmXLOw46&|BN&e- zU5JF$!VC#NVM>&@`Z#+~6;z$YW}Fw|QQ*C4VF0q81QMg^YB6)Z+X7Ou`&QG=6p>F_ zABsGHqCL9^YfaCD&h<(-k>Dri@Lu%!N^u-PA=oJ%It5hDNAfO2pctnq#K}Soutf*} zXr@AyNV)nC%qv0QInIzsJcIru8M!v@J!B?oV1>>>ZZTW{%_^(#*J-=e&j5o-y=rZ4 zXo9Yo{mrN{DKib`P+b~Ph6TPu&I0XB)dVkItokLjnBc1Y0l-VJRDUqp&KK`iGLzsV z3IE96-vOLM&!LeK%#2(mBOrDXOdOfT0|S|&1w@7mn6p>jb7~q%`zz}91n{yP(1jGf z4pu??dlL3bEKZxS%Bn6LZ@kg7hn1`TdSKdfz-2S8;WJyVffgOHHKlYj?q#zSJ>+vn z)hhO%^k5ULK!*`$OGURO0Ejq*gop^P&v5q{s{qC@Unh~shNM5SLcLH@D?Jh|tUmjk zUPxSMksU{;7NB`^Oj!SL(LT!%`>H~kN*41^0x1QQ--B5Ss<2;GpU?;aXaiK1K^=Id`q(=bvjy;UG()jROq5(l}$sjc&)h|y=W2f#~Y;{fDk`j8*RrM zg{q20Qb(pRcJrmo_TD@FF#IK~(Iq-zsgY7Gpvx^DYVeQi*P4I7^23g0g&T(tkpf67 z5PjD}P`L$BQ(&$`8g^@!Utep6kpCQV(Dz6lh$*gVMEPpcdBZ|Ulp|p^il9nL@LG2C z*qkp@rw*VJEB!et$O3N{b`y@&dtQCINeS1BZ|ZgBbQ$!jG4<{iD$f#L&Re=Rc+tR2 z;Iq^ow7R2M>>v;7le7r))L?4aMg=4f6Hs6J$#p*vN5^vE;df#Edhy7)5lbeClOgxR zFs=dlqm*O9XK!(brU1QliTgV>Mz7WqT(u$ZYJe%Gh}vmUHnio>eMQBM&f#iLL6K#w zLB^Q(WJ9R_SUJvCSW`&7YT0*#&M(1y>}_pe46TE_?+Tq?g~KLHpbz=Cy{CX>X=vN~ z7GcBT;^+fRUDjvp(T_lx4mo4F9E$h382p;9S9LAm8i}sEwT+XI8EFoc+_!~vlU5Zh zrz-K27Zv)#y&?tWTfLi)7=Cw0$M0a)lgLUlC)EbXb2FgrRBgzQ`P^VUVMlJy2Z|6W zSyFlB(H%eTB-boad=8QoCO5#L$7!NvaWWbg{M)+_k%PRdZ7*hOeUQH9AX*61$ytXVPP&SGKT~R3$_oSaE@Z+{JO|)7ZeI$P!f+Mg> z$AgP}4StA08mE&|@1h8!lu_tT7MtYuqqgsX!5k7#yFcE#f7@Gls_Xi6Y=o~yfsqTK z8fN*p^F%_3k1l>2m`Oe{t{-gfD~wwMtYEevw44_jI%6PJ40*JbFJbBPG$KavkkmDO{;gHoxg7VvDvm3snfw`2 zZL`8@D@2pVFP3CBvuj=aHnpZ%!56Q<^J-c?n6JKwph9|=<-VhsGnxZZs5>*PHsvs} zq|GCV{!#~VgaVXP$|DblK`>+7%c(hQuY@fX;P|AwtkDt74iN!#BS4B)YL!TOQvVUa zz`-+W$=43hQAuuB(ThcQ# znmCn1Qb%Rjj6@?2^flhl>tFeind01;O(ay#zh6hVM*%qZ?(0{~mM{trQc77{a2_~w zX{vH0H71enFiQl$_s>vsybO#$WVnUd3_Fms^^wywejX>1qLVp?<#z^Hq3)mktE>aF z_A|M|l`=8k9&kkt1cr+A-v8crq_0CPGH6QzUC@+I+{<_Pp)rV6;;AETTOvOgMUHJZ zMw}z7A^`sB#nSYS|7tOn@}*$V4=Pkyb9o3GQ<@hM79e|KHO}z#NL~Rxh|6QkS)ZNO zYNb9Da6=cxe%5z(AiU!I|GX^;_nB97`{k=--=SjRRz0q6e1gp_iYOr7P(MyHbMB0p zw{0WRlJ&P;Wp<_x<$s~-*uCe|qi}LUh07DA4!qhz<8ye3~BvK|6?)ibT;E zq6Me5mALy>E${AJ5GATjOHIAbe1pLu`qI_LD2k&qhNcn=exXTdaOn$S~_g&-^|xIMgue8E`*a#=NBUCZ2H@2x4? zC^J;1twtszXcu34n>m{r|G)e;Y3LlFmm{h5a)Z%rfsm4Su9 zmInPk`3A3|P5J*%^6P&F%eWX>{%0A}{~j!3WnxJJ#v@CUq5<^=_HF%31KJJ_0NxvB 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

uRfa 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 Ee^ZZqjQ{`u delta 178992 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Ûp;3@WO0&!6RT!E0IV8VP%yD<7_!wE z7vNJh9Dol}U<1>7{VTu{5;d$rnrPUla198-)X^IB2RO|tuy~Y1f$DH{1bnh;fU1mR zajXVlmWT?+o|Bf$M{Aqn-sO!pIdBVBE)0Fc-&DT?L^^3Q+#2N(q2Ph7L0e zn7?470smxiuz)pHP0H|46QQ^O%y1Z%hS-Q{D0Btfv%pwI)ffRn^%#(W87DR_fW?6Z z@Nue+9q`o;W$JqtXy)+LP65WTA8Ij%M1ckv6mW43Ck8h$)Vl&}*s(*;Ou_Y$I*SRa z5kDY=ZWSYhDKR1fqj#tx4fg?qV*QEhra>^ffq}d}|1`KA0INE7rN=;`rdjYE#0<=3 z)qU>&XfdFBf(!9F2J3qkuvT1?!gLQ0%N1aid%}Pp*QqdSfr_DyNKL4QH5wZ$LqI-& z&r6%#O}WixBuF=gK+xVo48&^;;6iIG1P;6pN@_eZrYY#d@Ifia|G0ew5rcOjA~5>K z6+R&3afu1jbqM+h7H$PpxrULzXX^IVseTVc zO5wQxJls;Q@bvQs#qH~Q1sGt0qzsR$T&v>2lX6Xq4Fl#_s%Huy#?d$%DYs^g@#(`3 zOk7kYDU2x~FC%7Pl44jjz;zvr<#AMk@jZvFO1UY)T{f)ws|iDNzzIM}dAMy?N>}w7 hR3@bMlAUR1W1iPOw=?b29G?0SNV8tO+(x^b{XdCiRKEZK diff --git a/ecc.c b/ecc.c index e5b8e4d..2c50a5f 100644 --- a/ecc.c +++ b/ecc.c @@ -22,6 +22,9 @@ /* size of our temp buffers for exported keys */ #define ECC_BUF_SIZE 160 +/* max private key size */ +#define ECC_MAXSIZE 66 + /* This holds the key settings. ***MUST*** be organized by size from smallest to largest. */ static const struct { int size; @@ -222,9 +225,6 @@ void ecc_find_base(void) #endif - - - static int is_valid_idx(int n) { int x; @@ -613,6 +613,7 @@ int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key) /* find key size */ for (x = 0; (keysize > sets[x].size) && (sets[x].size != 0); x++); keysize = sets[x].size; + _ARGCHK(keysize <= ECC_MAXSIZE); if (sets[x].size == 0) { return CRYPT_INVALID_KEYSIZE; @@ -621,7 +622,7 @@ int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key) /* allocate ram */ base = NULL; - buf = XMALLOC(128); + buf = XMALLOC(ECC_MAXSIZE); if (buf == NULL) { return CRYPT_MEM; } @@ -669,7 +670,7 @@ __ERR: mp_clear(&prime); __ERR2: #ifdef CLEAN_STACK - zeromem(buf, 128); + zeromem(buf, ECC_MAXSIZE); #endif XFREE(buf); diff --git a/fortuna.c b/fortuna.c index 44ba044..5d81255 100644 --- a/fortuna.c +++ b/fortuna.c @@ -274,7 +274,9 @@ int fortuna_export(unsigned char *out, unsigned long *outlen, prng_state *prng) } /* now hash it */ - sha256_init(md); + if ((err = sha256_init(md)) != CRYPT_OK) { + goto __ERR; + } if ((err = sha256_process(md, out+x*32, 32)) != CRYPT_OK) { goto __ERR; } diff --git a/hash_filehandle.c b/hash_filehandle.c index 777588a..cf179e0 100644 --- a/hash_filehandle.c +++ b/hash_filehandle.c @@ -31,9 +31,11 @@ int hash_filehandle(int hash, FILE *in, unsigned char *dst, unsigned long *outle if (*outlen < hash_descriptor[hash].hashsize) { return CRYPT_BUFFER_OVERFLOW; } - *outlen = hash_descriptor[hash].hashsize; + if ((err = hash_descriptor[hash].init(&md)) != CRYPT_OK) { + return err; + } - hash_descriptor[hash].init(&md); + *outlen = hash_descriptor[hash].hashsize; do { x = fread(buf, 1, sizeof(buf), in); if ((err = hash_descriptor[hash].process(&md, buf, x)) != CRYPT_OK) { diff --git a/hash_memory.c b/hash_memory.c index 89abb85..2c87d76 100644 --- a/hash_memory.c +++ b/hash_memory.c @@ -32,7 +32,9 @@ int hash_memory(int hash, const unsigned char *data, unsigned long len, unsigned return CRYPT_MEM; } - hash_descriptor[hash].init(md); + if ((err = hash_descriptor[hash].init(md)) != CRYPT_OK) { + goto __ERR; + } if ((err = hash_descriptor[hash].process(md, data, len)) != CRYPT_OK) { goto __ERR; } diff --git a/hmac_done.c b/hmac_done.c index 62ebe47..b31460b 100644 --- a/hmac_done.c +++ b/hmac_done.c @@ -75,7 +75,9 @@ int hmac_done(hmac_state *hmac, unsigned char *hashOut, unsigned long *outlen) } /* Now calculate the "outer" hash for step (5), (6), and (7) */ - hash_descriptor[hash].init(&hmac->md); + if ((err = hash_descriptor[hash].init(&hmac->md)) != CRYPT_OK) { + goto __ERR; + } if ((err = hash_descriptor[hash].process(&hmac->md, buf, HMAC_BLOCKSIZE)) != CRYPT_OK) { goto __ERR; } diff --git a/hmac_init.c b/hmac_init.c index a1cc0b5..0d894f1 100644 --- a/hmac_init.c +++ b/hmac_init.c @@ -91,7 +91,10 @@ int hmac_init(hmac_state *hmac, int hash, const unsigned char *key, unsigned lon } /* Pre-pend that to the hash data */ - hash_descriptor[hash].init(&hmac->md); + if ((err = hash_descriptor[hash].init(&hmac->md)) != CRYPT_OK) { + goto __ERR; + } + if ((err = hash_descriptor[hash].process(&hmac->md, buf, HMAC_BLOCKSIZE)) != CRYPT_OK) { goto __ERR; } diff --git a/ltc_tommath.h b/ltc_tommath.h index 3276141..896d389 100644 --- a/ltc_tommath.h +++ b/ltc_tommath.h @@ -1,4 +1,3 @@ - /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -21,7 +20,8 @@ #include #include #include -#include + +#include #undef MIN #define MIN(x,y) ((x)<(y)?(x):(y)) @@ -41,6 +41,14 @@ extern "C" { #endif + +/* detect 64-bit mode if possible */ +#if defined(__x86_64__) + #if !(defined(MP_64BIT) && defined(MP_16BIT) && defined(MP_8BIT)) + #define MP_64BIT + #endif +#endif + /* some default configurations. * * A "mp_digit" must be able to hold DIGIT_BIT + 1 bits @@ -62,7 +70,7 @@ extern "C" { typedef signed long long long64; #endif - typedef ulong64 mp_digit; + typedef unsigned long mp_digit; typedef unsigned long mp_word __attribute__ ((mode(TI))); #define DIGIT_BIT 60 @@ -101,16 +109,12 @@ extern "C" { #define XFREE free #define XREALLOC realloc #define XCALLOC calloc - #define XMEMSET memset - #define XMEMCPY memcpy #else /* prototypes for our heap functions */ - void *XMALLOC(size_t n); - void *REALLOC(void *p, size_t n); - void *XCALLOC(size_t n, size_t s); - void XFREE(void *p); - void *XMEMCPY(void *dest, const void *src, size_t n); - int XMEMCMP(const void *s1, const void *s2, size_t n); + extern void *XMALLOC(size_t n); + extern void *REALLOC(void *p, size_t n); + extern void *XCALLOC(size_t n, size_t s); + extern void XFREE(void *p); #endif #endif @@ -159,7 +163,7 @@ extern int KARATSUBA_MUL_CUTOFF, /* default precision */ #ifndef MP_PREC - #ifdef MP_LOW_MEM + #ifndef MP_LOW_MEM #define MP_PREC 64 /* default digits of precision */ #else #define MP_PREC 8 /* default digits of precision */ @@ -547,13 +551,13 @@ 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 mp_invmod_slow (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); - const char *mp_s_rmap; - +extern const char *mp_s_rmap; #ifdef __cplusplus } diff --git a/makefile b/makefile index f65aa5c..c90b88d 100644 --- a/makefile +++ b/makefile @@ -4,7 +4,7 @@ # Modified by Clay Culver # The version -VERSION=0.98 +VERSION=0.99 # Compiler and Linker Names #CC=gcc @@ -19,13 +19,13 @@ CFLAGS += -c -I./ -Wall -Wsign-compare -W -Wshadow # -Werror # optimize for SPEED -#CFLAGS += -O3 -funroll-loops +#CFLAGS += -O3 -funroll-all-loops #add -fomit-frame-pointer. hinders debugging! -CFLAGS += -fomit-frame-pointer +#CFLAGS += -fomit-frame-pointer # optimize for SIZE -CFLAGS += -Os +CFLAGS += -Os -DSMALL_CODE # compile for DEBUGING (required for ccmalloc checking!!!) #CFLAGS += -g3 @@ -82,7 +82,7 @@ blowfish.o des.o safer_tab.o safer.o saferp.o rc2.o xtea.o \ rc6.o rc5.o cast5.o noekeon.o twofish.o skipjack.o \ \ md2.o md4.o md5.o sha1.o sha256.o sha512.o tiger.o whirl.o \ -rmd128.o rmd160.o \ +rmd128.o rmd160.o chc.o \ \ packet_store_header.o packet_valid_header.o \ \ @@ -114,7 +114,11 @@ pkcs_1_v15_es_encode.o pkcs_1_v15_es_decode.o pkcs_1_v15_sa_encode.o pkcs_1_v15_ \ pkcs_5_1.o pkcs_5_2.o \ \ +der_encode_integer.o der_decode_integer.o der_length_integer.o \ +der_put_multi_integer.o der_get_multi_integer.o \ +\ burn_stack.o zeromem.o \ +\ $(MPIOBJECT) TESTOBJECTS=demos/test.o @@ -134,7 +138,7 @@ COMPRESSED=crypt-$(VERSION).tar.bz2 crypt-$(VERSION).zip HEADERS=ltc_tommath.h mycrypt_cfg.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 mycrypt_pkcs.h +mycrypt_custom.h mycrypt_pkcs.h tommath_class.h tommath_superclass.h #The default rule for make builds the libtomcrypt library. default:library @@ -187,15 +191,22 @@ install: library docs install -g root -o root $(HEADERS) $(DESTDIR)$(INCPATH) install -g root -o root doc/crypt.pdf $(DESTDIR)$(DATAPATH) +install_lib: library + install -d -g root -o root $(DESTDIR)$(LIBPATH) + install -d -g root -o root $(DESTDIR)$(INCPATH) + install -g root -o root $(LIBNAME) $(DESTDIR)$(LIBPATH) + install -g root -o root $(HEADERS) $(DESTDIR)$(INCPATH) + #This rule cleans the source tree of all compiled code, not including the pdf #documentation. clean: rm -f $(OBJECTS) $(TESTOBJECTS) $(HASHOBJECTS) $(CRYPTOBJECTS) $(SMALLOBJECTS) $(LEFTOVERS) $(LIBNAME) rm -f $(TEST) $(HASH) $(COMPRESSED) $(PROFS) $(PROF) $(TVS) $(TV) - rm -f *.a *.dll *stackdump *.lib *.exe *.obj demos/*.obj demos/*.o *.bat *.txt *.il *.da demos/*.il demos/*.da *.dyn *.dpi \ + rm -f *.la *.lo *.o *.a *.dll *stackdump *.lib *.exe *.obj demos/*.obj demos/*.o *.bat *.txt *.il *.da demos/*.il demos/*.da *.dyn *.dpi \ *.gcda *.gcno demos/*.gcno demos/*.gcda *~ doc/* cd demos/test ; make clean - + rm -rf .libs demos/.libs demos/test/.libs + #This builds the crypt.pdf file. Note that the rm -f *.pdf has been removed #from the clean command! This is because most people would like to keep the #nice pre-compiled crypt.pdf that comes with libtomcrypt! We only need to @@ -230,12 +241,6 @@ profiled: rm *.o *.a x86_prof make CFLAGS="$(CFLAGS) -fprofile-use" EXTRALIBS=-lgcov x86_prof -#beta -beta: clean - cd .. ; rm -rf crypt* libtomcrypt-$(VERSION)-beta ; mkdir libtomcrypt-$(VERSION)-beta ; \ - cp -R ./libtomcrypt/* ./libtomcrypt-$(VERSION)-beta/ ; tar -c libtomcrypt-$(VERSION)-beta/* > crypt-$(VERSION)-beta.tar ; \ - bzip2 -9vv crypt-$(VERSION)-beta.tar ; zip -9 -r crypt-$(VERSION)-beta.zip libtomcrypt-$(VERSION)-beta/* - #zipup the project (take that!) zipup: clean docs cd .. ; rm -rf crypt* libtomcrypt-$(VERSION) ; mkdir libtomcrypt-$(VERSION) ; \ diff --git a/makefile.cygwin_dll b/makefile.cygwin_dll index 5683dc6..5e11b7c 100644 --- a/makefile.cygwin_dll +++ b/makefile.cygwin_dll @@ -7,13 +7,13 @@ default: ltc_dll CFLAGS += -I./ -Wall -Wsign-compare -W -Wno-unused -Wshadow -mno-cygwin -DWIN32 # optimize for SPEED -#CFLAGS += -O3 -funroll-loops +CFLAGS += -O3 -funroll-all-loops #add -fomit-frame-pointer. v3.2 is buggy for certain platforms! -#CFLAGS += -fomit-frame-pointer +CFLAGS += -fomit-frame-pointer # optimize for SIZE -CFLAGS += -Os +#CFLAGS += -Os #Leave MPI built-in or force developer to link against libtommath? MPIOBJECT=mpi.o @@ -28,7 +28,7 @@ crypt_find_cipher_id.o crypt_find_prng.o crypt_prng_is_valid.o \ crypt_unregister_cipher.o crypt_cipher_is_valid.o crypt_find_hash.o \ crypt_hash_descriptor.o crypt_register_cipher.o crypt_unregister_hash.o \ \ -sprng.o fortuna.o sober128.o yarrow.o rc4.o rng_get_bytes.o rng_make_prng.o \ +sober128.o fortuna.o sprng.o yarrow.o rc4.o rng_get_bytes.o rng_make_prng.o \ \ rand_prime.o is_prime.o \ \ @@ -47,7 +47,7 @@ blowfish.o des.o safer_tab.o safer.o saferp.o rc2.o xtea.o \ rc6.o rc5.o cast5.o noekeon.o twofish.o skipjack.o \ \ md2.o md4.o md5.o sha1.o sha256.o sha512.o tiger.o whirl.o \ -rmd128.o rmd160.o \ +rmd128.o rmd160.o chc.o \ \ packet_store_header.o packet_valid_header.o \ \ @@ -79,7 +79,11 @@ pkcs_1_v15_es_encode.o pkcs_1_v15_es_decode.o pkcs_1_v15_sa_encode.o pkcs_1_v15_ \ pkcs_5_1.o pkcs_5_2.o \ \ +der_encode_integer.o der_decode_integer.o der_length_integer.o \ +der_put_multi_integer.o der_get_multi_integer.o \ +\ burn_stack.o zeromem.o \ +\ $(MPIOBJECT) #ciphers come in two flavours... enc+dec and enc diff --git a/makefile.icc b/makefile.icc index f73a323..ee7ba54 100644 --- a/makefile.icc +++ b/makefile.icc @@ -98,7 +98,7 @@ blowfish.o des.o safer_tab.o safer.o saferp.o rc2.o xtea.o \ rc6.o rc5.o cast5.o noekeon.o twofish.o skipjack.o \ \ md2.o md4.o md5.o sha1.o sha256.o sha512.o tiger.o whirl.o \ -rmd128.o rmd160.o \ +rmd128.o rmd160.o chc.o \ \ packet_store_header.o packet_valid_header.o \ \ @@ -130,7 +130,11 @@ pkcs_1_v15_es_encode.o pkcs_1_v15_es_decode.o pkcs_1_v15_sa_encode.o pkcs_1_v15_ \ pkcs_5_1.o pkcs_5_2.o \ \ +der_encode_integer.o der_decode_integer.o der_length_integer.o \ +der_put_multi_integer.o der_get_multi_integer.o \ +\ burn_stack.o zeromem.o \ +\ $(MPIOBJECT) diff --git a/makefile.msvc b/makefile.msvc index 6209827..a5b5ef9 100644 --- a/makefile.msvc +++ b/makefile.msvc @@ -18,7 +18,7 @@ crypt_find_cipher_id.obj crypt_find_prng.obj crypt_prng_is_valid.obj crypt_unregister_cipher.obj crypt_cipher_is_valid.obj crypt_find_hash.obj \ crypt_hash_descriptor.obj crypt_register_cipher.obj crypt_unregister_hash.obj \ \ -sprng.obj fortuna.obj sober128.obj yarrow.obj rc4.obj rng_get_bytes.obj rng_make_prng.obj \ +sober128.obj fortuna.obj sprng.obj yarrow.obj rc4.obj rng_get_bytes.obj rng_make_prng.obj \ \ rand_prime.obj is_prime.obj \ \ @@ -37,7 +37,7 @@ blowfish.obj des.obj safer_tab.obj safer.obj saferp.obj rc2.obj xtea.obj \ rc6.obj rc5.obj cast5.obj noekeon.obj twofish.obj skipjack.obj \ \ md2.obj md4.obj md5.obj sha1.obj sha256.obj sha512.obj tiger.obj whirl.obj \ -rmd128.obj rmd160.obj \ +rmd128.obj rmd160.obj chc.obj \ \ packet_store_header.obj packet_valid_header.obj \ \ @@ -69,7 +69,11 @@ pkcs_1_v15_es_encode.obj pkcs_1_v15_es_decode.obj pkcs_1_v15_sa_encode.obj pkcs_ \ pkcs_5_1.obj pkcs_5_2.obj \ \ +der_encode_integer.obj der_decode_integer.obj der_length_integer.obj \ +der_put_multi_integer.obj der_get_multi_integer.obj \ +\ burn_stack.obj zeromem.obj \ +\ $(MPIOBJECT) #ciphers come in two flavours... enc+dec and enc diff --git a/makefile.shared b/makefile.shared new file mode 100644 index 0000000..5f5f5b8 --- /dev/null +++ b/makefile.shared @@ -0,0 +1,186 @@ +# MAKEFILE for linux GCC +# +# Tom St Denis +# Modified by Clay Culver + +# The version +VERSION=0:99 + +# Compiler and Linker Names +CC=libtool --mode=compile gcc + +# Archiver [makes .a files] +AR=libtool --mode=link + +# Compilation flags. Note the += does not write over the user's CFLAGS! +CFLAGS += -c -I./ -Wall -Wsign-compare -W -Wshadow +# -Werror + +# optimize for SPEED +CFLAGS += -O3 -funroll-all-loops + +#add -fomit-frame-pointer. hinders debugging! +CFLAGS += -fomit-frame-pointer + +# optimize for SIZE +#CFLAGS += -Os + +# compile for DEBUGING (required for ccmalloc checking!!!) +#CFLAGS += -g3 + +#These flags control how the library gets built. + +#Output filenames for various targets. +LIBNAME=libtomcrypt.la +HASH=hashsum +CRYPT=encrypt +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. +DESTDIR= +LIBPATH=/usr/lib +INCPATH=/usr/include +DATAPATH=/usr/share/doc/libtomcrypt/pdf + +#List of objects to compile. + +#Leave MPI built-in or force developer to link against libtommath? +MPIOBJECT=mpi.o + +#If you don't want mpi.o then add this +#MPISHARED=$(LIBPATH)/libtommath.la + +OBJECTS=error_to_string.o mpi_to_ltc_error.o base64_encode.o base64_decode.o \ +\ +crypt.o crypt_find_cipher.o crypt_find_hash_any.o \ +crypt_hash_is_valid.o crypt_register_hash.o crypt_unregister_prng.o \ +crypt_argchk.o crypt_find_cipher_any.o crypt_find_hash_id.o \ +crypt_prng_descriptor.o crypt_register_prng.o crypt_cipher_descriptor.o \ +crypt_find_cipher_id.o crypt_find_prng.o crypt_prng_is_valid.o \ +crypt_unregister_cipher.o crypt_cipher_is_valid.o crypt_find_hash.o \ +crypt_hash_descriptor.o crypt_register_cipher.o crypt_unregister_hash.o \ +\ +sober128.o fortuna.o sprng.o yarrow.o rc4.o rng_get_bytes.o rng_make_prng.o \ +\ +rand_prime.o is_prime.o \ +\ +ecc.o dh.o \ +\ +rsa_decrypt_key.o rsa_encrypt_key.o rsa_exptmod.o rsa_free.o rsa_make_key.o \ +rsa_sign_hash.o rsa_verify_hash.o rsa_export.o rsa_import.o tim_exptmod.o \ +rsa_v15_encrypt_key.o rsa_v15_decrypt_key.o rsa_v15_sign_hash.o rsa_v15_verify_hash.o \ +\ +dsa_export.o dsa_free.o dsa_import.o dsa_make_key.o dsa_sign_hash.o \ +dsa_verify_hash.o dsa_verify_key.o \ +\ +aes.o aes_enc.o \ +\ +blowfish.o des.o safer_tab.o safer.o saferp.o rc2.o xtea.o \ +rc6.o rc5.o cast5.o noekeon.o twofish.o skipjack.o \ +\ +md2.o md4.o md5.o sha1.o sha256.o sha512.o tiger.o whirl.o \ +rmd128.o rmd160.o chc.o \ +\ +packet_store_header.o packet_valid_header.o \ +\ +eax_addheader.o eax_decrypt.o eax_decrypt_verify_memory.o eax_done.o eax_encrypt.o \ +eax_encrypt_authenticate_memory.o eax_init.o eax_test.o \ +\ +ocb_decrypt.o ocb_decrypt_verify_memory.o ocb_done_decrypt.o ocb_done_encrypt.o \ +ocb_encrypt.o ocb_encrypt_authenticate_memory.o ocb_init.o ocb_ntz.o \ +ocb_shift_xor.o ocb_test.o s_ocb_done.o \ +\ +omac_done.o omac_file.o omac_init.o omac_memory.o omac_process.o omac_test.o \ +\ +pmac_done.o pmac_file.o pmac_init.o pmac_memory.o pmac_ntz.o pmac_process.o \ +pmac_shift_xor.o pmac_test.o \ +\ +cbc_start.o cbc_encrypt.o cbc_decrypt.o cbc_getiv.o cbc_setiv.o \ +cfb_start.o cfb_encrypt.o cfb_decrypt.o cfb_getiv.o cfb_setiv.o \ +ofb_start.o ofb_encrypt.o ofb_decrypt.o ofb_getiv.o ofb_setiv.o \ +ctr_start.o ctr_encrypt.o ctr_decrypt.o ctr_getiv.o ctr_setiv.o \ +ecb_start.o ecb_encrypt.o ecb_decrypt.o \ +\ +hash_file.o hash_filehandle.o hash_memory.o \ +\ +hmac_done.o hmac_file.o hmac_init.o hmac_memory.o hmac_process.o hmac_test.o \ +\ +pkcs_1_mgf1.o pkcs_1_oaep_encode.o pkcs_1_oaep_decode.o \ +pkcs_1_pss_encode.o pkcs_1_pss_decode.o pkcs_1_i2osp.o pkcs_1_os2ip.o \ +pkcs_1_v15_es_encode.o pkcs_1_v15_es_decode.o pkcs_1_v15_sa_encode.o pkcs_1_v15_sa_decode.o \ +\ +pkcs_5_1.o pkcs_5_2.o \ +\ +der_encode_integer.o der_decode_integer.o der_length_integer.o \ +der_put_multi_integer.o der_get_multi_integer.o \ +\ +burn_stack.o zeromem.o \ +\ +$(MPIOBJECT) + +TESTOBJECTS=demos/test.o +HASHOBJECTS=demos/hashsum.o +CRYPTOBJECTS=demos/encrypt.o +SMALLOBJECTS=demos/small.o +PROFS=demos/x86_prof.o +TVS=demos/tv_gen.o + +#Files left over from making the crypt.pdf. +LEFTOVERS=*.dvi *.log *.aux *.toc *.idx *.ilg *.ind *.out + +#Compressed filenames +COMPRESSED=crypt-$(VERSION).tar.bz2 crypt-$(VERSION).zip + +#Header files used by libtomcrypt. +HEADERS=ltc_tommath.h mycrypt_cfg.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 mycrypt_pkcs.h tommath_class.h tommath_superclass.h + +#The default rule for make builds the libtomcrypt library. +default:library + +#ciphers come in two flavours... enc+dec and enc +aes_enc.o: aes.c aes_tab.c + $(CC) $(CFLAGS) -DENCRYPT_ONLY -c aes.c -o aes_enc.o + +#These are the rules to make certain object files. +aes.o: aes.c aes_tab.c +twofish.o: twofish.c twofish_tab.c +whirl.o: whirl.c whirltab.c +ecc.o: ecc.c ecc_sys.c +dh.o: dh.c dh_sys.c +sha512.o: sha512.c sha384.c +sha256.o: sha256.c sha224.c + +#This rule makes the libtomcrypt library. +library: $(LIBNAME) + +$(LIBNAME): $(OBJECTS) + libtool --mode=link gcc $(CFLAGS) *.lo -o libtomcrypt.la -rpath $(LIBPATH) -version-info $(VERSION) + libtool --mode=link gcc $(CFLAGS) *.o -o libtomcrypt.a + libtool --mode=install install -c libtomcrypt.la $(LIBPATH)/libtomcrypt.la + install -d -g root -o root $(DESTDIR)$(INCPATH) + install -g root -o root $(HEADERS) $(DESTDIR)$(INCPATH) + +#This rule makes the hash program included with libtomcrypt +hashsum: library + gcc $(CFLAGS) demos/hashsum.c -o hashsum.o + libtool --mode=link gcc -o hashsum hashsum.o -ltomcrypt $(MPISHARED) + +#makes the crypt program +crypt: library + gcc $(CFLAGS) demos/encrypt.c -o encrypt.o + libtool --mode=link gcc -o crypt encrypt.o -ltomcrypt $(MPISHARED) + +x86_prof: library + gcc $(CFLAGS) demos/x86_prof.c -o x86_prof.o + libtool --mode=link gcc -o x86_prof x86_prof.o -ltomcrypt $(MPISHARED) $(EXTRALIBS) + +tv_gen: library $(TVS) + gcc $(CFLAGS) demos/tv_gen.c -o tv_gen.o + libtool --mode=link gcc -o tv_gen tv_gen.o -ltomcrypt $(MPISHARED) diff --git a/md2.c b/md2.c index 30ac4ec..8e2a987 100644 --- a/md2.c +++ b/md2.c @@ -90,7 +90,7 @@ static void md2_compress(hash_state *md) } } -void md2_init(hash_state *md) +int md2_init(hash_state *md) { _ARGCHK(md != NULL); @@ -99,6 +99,7 @@ void md2_init(hash_state *md) zeromem(md->md2.chksum, sizeof(md->md2.chksum)); zeromem(md->md2.buf, sizeof(md->md2.buf)); md->md2.curlen = 0; + return CRYPT_OK; } int md2_process(hash_state *md, const unsigned char *buf, unsigned long len) diff --git a/md4.c b/md4.c index 5c2ea11..0e0cc6b 100644 --- a/md4.c +++ b/md4.c @@ -68,9 +68,9 @@ const struct _hash_descriptor md4_desc = } #ifdef CLEAN_STACK -static void _md4_compress(hash_state *md, unsigned char *buf) +static int _md4_compress(hash_state *md, unsigned char *buf) #else -static void md4_compress(hash_state *md, unsigned char *buf) +static int md4_compress(hash_state *md, unsigned char *buf) #endif { ulong32 x[16], a, b, c, d; @@ -147,17 +147,21 @@ static void md4_compress(hash_state *md, unsigned char *buf) md->md4.state[1] = md->md4.state[1] + b; md->md4.state[2] = md->md4.state[2] + c; md->md4.state[3] = md->md4.state[3] + d; + + return CRYPT_OK; } #ifdef CLEAN_STACK -static void md4_compress(hash_state *md, unsigned char *buf) +static int md4_compress(hash_state *md, unsigned char *buf) { - _md4_compress(md, buf); + int err; + err = _md4_compress(md, buf); burn_stack(sizeof(ulong32) * 20 + sizeof(int)); + return err; } #endif -void md4_init(hash_state * md) +int md4_init(hash_state * md) { _ARGCHK(md != NULL); md->md4.state[0] = 0x67452301UL; @@ -166,6 +170,7 @@ void md4_init(hash_state * md) md->md4.state[3] = 0x10325476UL; md->md4.length = 0; md->md4.curlen = 0; + return CRYPT_OK; } HASH_PROCESS(md4_process, md4_compress, md4, 64) diff --git a/md5.c b/md5.c index 8f6e1ea..5339169 100644 --- a/md5.c +++ b/md5.c @@ -81,9 +81,9 @@ static const ulong32 Korder[64] = { #endif #ifdef CLEAN_STACK -static void _md5_compress(hash_state *md, unsigned char *buf) +static int _md5_compress(hash_state *md, unsigned char *buf) #else -static void md5_compress(hash_state *md, unsigned char *buf) +static int md5_compress(hash_state *md, unsigned char *buf) #endif { ulong32 i, W[16], a, b, c, d; @@ -194,17 +194,21 @@ static void md5_compress(hash_state *md, unsigned char *buf) md->md5.state[1] = md->md5.state[1] + b; md->md5.state[2] = md->md5.state[2] + c; md->md5.state[3] = md->md5.state[3] + d; + + return CRYPT_OK; } #ifdef CLEAN_STACK -static void md5_compress(hash_state *md, unsigned char *buf) +static int md5_compress(hash_state *md, unsigned char *buf) { - _md5_compress(md, buf); + int err; + err = _md5_compress(md, buf); burn_stack(sizeof(ulong32) * 21); + return err; } #endif -void md5_init(hash_state * md) +int md5_init(hash_state * md) { _ARGCHK(md != NULL); md->md5.state[0] = 0x67452301UL; @@ -213,6 +217,7 @@ void md5_init(hash_state * md) md->md5.state[3] = 0x10325476UL; md->md5.curlen = 0; md->md5.length = 0; + return CRYPT_OK; } HASH_PROCESS(md5_process, md5_compress, md5, 64) diff --git a/mpi.c b/mpi.c index dc99927..2ddd0de 100644 --- a/mpi.c +++ b/mpi.c @@ -1,4 +1,6 @@ /* Start: bn_error.c */ +#include +#ifdef BN_ERROR_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -13,7 +15,6 @@ * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include static const struct { int code; @@ -40,10 +41,13 @@ char *mp_error_to_string(int code) return "Invalid error code"; } +#endif /* End: bn_error.c */ /* Start: bn_fast_mp_invmod.c */ +#include +#ifdef BN_FAST_MP_INVMOD_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -58,12 +62,11 @@ char *mp_error_to_string(int code) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* computes the modular inverse via binary extended euclidean algorithm, * that is c = 1/a mod b * - * Based on mp_invmod except this is optimized for the case where b is + * Based on slow invmod except this is optimized for the case where b is * odd as per HAC Note 14.64 on pp. 610 */ int @@ -187,10 +190,13 @@ top: __ERR:mp_clear_multi (&x, &y, &u, &v, &B, &D, NULL); return res; } +#endif /* End: bn_fast_mp_invmod.c */ /* Start: bn_fast_mp_montgomery_reduce.c */ +#include +#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -205,11 +211,10 @@ __ERR:mp_clear_multi (&x, &y, &u, &v, &B, &D, NULL); * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* computes xR**-1 == x (mod N) via Montgomery Reduction * - * This is an optimized implementation of mp_montgomery_reduce + * This is an optimized implementation of montgomery_reduce * which uses the comba method to quickly calculate the columns of the * reduction. * @@ -258,15 +263,6 @@ fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) /* now we proceed to zero successive digits * from the least significant upwards */ -#ifdef LTMSSE - // compute globals we'd like to have in MMX registers - asm ("movl $268435455,%%eax \n\t" //mm2 == MP_MASK - "movd %%eax,%%mm2 \n\t" - "movd %0,%%mm3 \n\t" //mm3 = rho - "movq (%1),%%mm0 \n\t" // W[ix] for ix=0 - ::"r"(rho),"r"(W):"%eax"); -#endif - for (ix = 0; ix < n->used; ix++) { /* mu = ai * m' mod b * @@ -274,13 +270,9 @@ fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) * by casting the value down to a mp_digit. Note this requires * that W[ix-1] have the carry cleared (see after the inner loop) */ -#ifndef LTMSSE register mp_digit mu; mu = (mp_digit) (((W[ix] & MP_MASK) * rho) & MP_MASK); -#else - asm("pmuludq %mm3,%mm0 \n\t" // multiply against rho - "pand %mm2,%mm0 \n\t"); // mu == mm0 -#endif + /* a = a + mu * m * b**i * * This is computed in place and on the fly. The multiplication @@ -308,33 +300,13 @@ fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) /* inner loop */ for (iy = 0; iy < n->used; iy++) { -#ifndef LTMSSE *_W++ += ((mp_word)mu) * ((mp_word)*tmpn++); -#else -// SSE version - asm ("movd (%0), %%mm1 \n\t" // load right side - "pmuludq %%mm0,%%mm1 \n\t" // multiply into left side - "paddq (%1),%%mm1 \n\t" // add 64-bit result out - "movq %%mm1,(%1)" // store result - :: "r"(tmpn), "r"(_W)); - // update pointers - ++tmpn; - ++_W; -#endif } } /* now fix carry for next digit, W[ix+1] */ -#ifndef LTMSSE W[ix + 1] += W[ix] >> ((mp_word) DIGIT_BIT); -#else - asm("movq (%0),%%mm0 \n\t" // W[ix] - "psrlq $28,%%mm0 \n\t" // W[ix]>>28 - "paddq 8(%0),%%mm0 \n\t" // W[ix+1] + W[ix]>>28 - "movq %%mm0,8(%0) " // store - ::"r"(&W[ix])); -#endif -} + } /* now we have to propagate the carries and * shift the words downward [all those least @@ -352,36 +324,35 @@ fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) /* alias for next word, where the carry goes */ _W = W + ++ix; + for (; ix <= n->used * 2 + 1; ix++) { + *_W++ += *_W1++ >> ((mp_word) DIGIT_BIT); + } + + /* copy out, A = A/b**n + * + * The result is A/b**n but instead of converting from an + * array of mp_word to mp_digit than calling mp_rshd + * we just copy them in the right order + */ + /* alias for destination word */ tmpx = x->dp; - for (; ix <= n->used * 2 + 1; ix++) { -#ifndef LTMSSE - *tmpx++ = (mp_digit)(*_W1 & ((mp_word) MP_MASK)); - *_W++ += *_W1++ >> ((mp_word) DIGIT_BIT); -#else - asm("movq %%mm0,%%mm1 \n\t" // copy of W[ix] - "psrlq $28,%%mm0 \n\t" // >>28 - "pand %%mm2,%%mm1 \n\t" // & with MP_MASK - "paddq (%0),%%mm0 \n\t" // += _W - "movd %%mm1,(%1) \n\t" // store it - ::"r"(_W),"r"(tmpx)); - ++_W; ++tmpx; -#endif + /* alias for shifted double precision result */ + _W = W + n->used; + + for (ix = 0; ix < n->used + 1; ix++) { + *tmpx++ = (mp_digit)(*_W++ & ((mp_word) MP_MASK)); } /* zero oldused digits, if the input a was larger than * m->used+1 we'll have to clear the digits */ - for (ix = n->used + 1; ix < olduse; ix++) { + for (; ix < olduse; ix++) { *tmpx++ = 0; } } -#ifdef LTMSSE - asm("emms"); -#endif - /* set the max used and clamp */ x->used = n->used + 1; mp_clamp (x); @@ -392,10 +363,13 @@ fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) } return MP_OKAY; } +#endif /* End: bn_fast_mp_montgomery_reduce.c */ /* Start: bn_fast_s_mp_mul_digs.c */ +#include +#ifdef BN_FAST_S_MP_MUL_DIGS_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -410,7 +384,6 @@ fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* Fast (comba) multiplier * @@ -431,8 +404,9 @@ fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) int fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) { - int olduse, res, pa, ix; - mp_word W[MP_WARRAY]; + int olduse, res, pa, ix, iz; + mp_digit W[MP_WARRAY]; + register mp_word _W; /* grow the destination as required */ if (c->alloc < digs) { @@ -441,68 +415,39 @@ fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) } } - /* clear temp buf (the columns) */ - memset (W, 0, sizeof (mp_word) * digs); + /* number of output digits to produce */ + pa = MIN(digs, a->used + b->used); - /* calculate the columns */ - pa = a->used; - for (ix = 0; ix < pa; ix++) { - /* this multiplier has been modified to allow you to - * control how many digits of output are produced. - * So at most we want to make upto "digs" digits of output. - * - * this adds products to distinct columns (at ix+iy) of W - * note that each step through the loop is not dependent on - * the previous which means the compiler can easily unroll - * the loop without scheduling problems - */ - { -#ifndef LTMSSE - register mp_digit tmpx; -#endif + /* clear the carry */ + _W = 0; + for (ix = 0; ix <= pa; ix++) { + int tx, ty; + int iy; + mp_digit *tmpx, *tmpy; - register mp_digit *tmpy; - register mp_word *_W; - register int iy, pb; + /* get offsets into the two bignums */ + ty = MIN(b->used-1, ix); + tx = ix - ty; - /* alias for the the word on the left e.g. A[ix] * A[iy] */ -#ifndef LTMSSE - tmpx = a->dp[ix]; -#else -// SSE: now we load the left side in mm0 - asm (" movd %0, %%mm0 " :: "r"(a->dp[ix])); -#endif - /* alias for the right side */ - tmpy = b->dp; + /* setup temp aliases */ + tmpx = a->dp + tx; + tmpy = b->dp + ty; - /* alias for the columns, each step through the loop adds a new - term to each column + /* this is the number of times the loop will iterrate, essentially its + while (tx++ < a->used && ty-- >= 0) { ... } */ - _W = W + ix; + iy = MIN(a->used-tx, ty+1); - /* the number of digits is limited by their placement. E.g. - we avoid multiplying digits that will end up above the # of - digits of precision requested - */ - pb = MIN (b->used, digs - ix); - - for (iy = 0; iy < pb; iy++) { -#ifndef LTMSSE - *_W++ += ((mp_word)tmpx) * ((mp_word)*tmpy++); -#else -// SSE version - asm ("movd (%0), %%mm1 \n\t" // load right side - "pmuludq %%mm0,%%mm1 \n\t" // multiply into left side - "paddq (%1), %%mm1 \n\t" // add 64-bit result out - "movq %%mm1,(%1)" // store result - :: "r"(tmpy), "r"(_W)); - // update pointers - ++tmpy; - ++_W; -#endif + /* execute loop */ + for (iz = 0; iz < iy; ++iz) { + _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--); } - } + /* store term */ + W[ix] = ((mp_digit)_W) & MP_MASK; + + /* make next carry */ + _W = _W >> ((mp_word)DIGIT_BIT); } /* setup dest */ @@ -511,80 +456,27 @@ fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) { register mp_digit *tmpc; - - /* At this point W[] contains the sums of each column. To get the - * correct result we must take the extra bits from each column and - * carry them down - * - * Note that while this adds extra code to the multiplier it - * saves time since the carry propagation is removed from the - * above nested loop.This has the effect of reducing the work - * from N*(N+N*c)==N**2 + c*N**2 to N**2 + N*c where c is the - * cost of the shifting. On very small numbers this is slower - * but on most cryptographic size numbers it is faster. - * - * In this particular implementation we feed the carries from - * behind which means when the loop terminates we still have one - * last digit to copy - */ tmpc = c->dp; - -#ifdef LTMSSE - // mm2 has W[ix-1] - asm("movq (%0),%%mm2"::"r"(W)); -#endif - - for (ix = 1; ix < digs; ix++) { -#ifndef LTMSSE - /* forward the carry from the previous temp */ - W[ix] += (W[ix - 1] >> ((mp_word) DIGIT_BIT)); - + for (ix = 0; ix < digs; ix++) { /* now extract the previous digit [below the carry] */ - *tmpc++ = (mp_digit) (W[ix - 1] & ((mp_word) MP_MASK)); - -#else - asm( - "movq (%0),%%mm1 \n\t" // W[ix] - "movd %%mm2,%%eax \n\t" // get 32-bit version of it W[ix-1] - "psrlq $28,%%mm2 \n\t" // W[ix-1] >> DIGIT_BIT ... must be 28 - "andl $268435455,%%eax \n\t" // & with MP_MASK against W[ix-1] - "paddq %%mm1,%%mm2 \n\t" // add them - "movl %%eax,(%1) \n\t" // store it - :: "r"(&W[ix]), "r"(tmpc) : "%eax"); - ++tmpc; -#endif - + *tmpc++ = W[ix]; } -#ifndef LTMSSE - /* fetch the last digit */ - *tmpc++ = (mp_digit) (W[digs - 1] & ((mp_word) MP_MASK)); -#else - // get last since we don't store into W[ix] anymore ;-) - asm("movd %%mm2,%%eax \n\t" - "andl $268435455,%%eax \n\t" // & with MP_MASK against W[ix-1] - "movl %%eax,(%0)" // store it - ::"r"(tmpc):"%eax"); - ++tmpc; -#endif - /* clear unused digits [that existed in the old copy of c] */ for (; ix < olduse; ix++) { *tmpc++ = 0; } } - -#ifdef LTMSSE - asm("emms"); -#endif - mp_clamp (c); return MP_OKAY; } +#endif /* End: bn_fast_s_mp_mul_digs.c */ /* Start: bn_fast_s_mp_mul_high_digs.c */ +#include +#ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -599,10 +491,9 @@ fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ - #include -/* this is a modified version of fast_s_mp_mul_digs that only produces - * output digits *above* digs. See the comments for fast_s_mp_mul_digs +/* this is a modified version of fast_s_mul_digs that only produces + * output digits *above* digs. See the comments for fast_s_mul_digs * to see how it works. * * This is used in the Barrett reduction since for one of the multiplications @@ -613,133 +504,78 @@ fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) int fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs) { - int oldused, newused, res, pa, pb, ix; - mp_word W[MP_WARRAY]; + int olduse, res, pa, ix, iz; + mp_digit W[MP_WARRAY]; + mp_word _W; - /* calculate size of product and allocate more space if required */ - newused = a->used + b->used + 1; - if (c->alloc < newused) { - if ((res = mp_grow (c, newused)) != MP_OKAY) { + /* grow the destination as required */ + pa = a->used + b->used; + if (c->alloc < pa) { + if ((res = mp_grow (c, pa)) != MP_OKAY) { return res; } } - /* like the other comba method we compute the columns first */ - pa = a->used; - pb = b->used; - memset (W + digs, 0, (pa + pb + 1 - digs) * sizeof (mp_word)); - for (ix = 0; ix < pa; ix++) { - { -#ifndef LTMSSE - register mp_digit tmpx; -#endif + /* number of output digits to produce */ + pa = a->used + b->used; + _W = 0; + for (ix = digs; ix <= pa; ix++) { + int tx, ty, iy; + mp_digit *tmpx, *tmpy; - register mp_digit *tmpy; - register int iy; - register mp_word *_W; + /* get offsets into the two bignums */ + ty = MIN(b->used-1, ix); + tx = ix - ty; - /* work todo, that is we only calculate digits that are at "digs" or above */ - iy = digs - ix; + /* setup temp aliases */ + tmpx = a->dp + tx; + tmpy = b->dp + ty; - /* copy of word on the left of A[ix] * B[iy] */ -#ifndef LTMSSE - tmpx = a->dp[ix]; -#else -//SSE we load tmpx into mm0 - asm (" movd %0, %%mm0 " :: "r"(a->dp[ix])); -#endif - - /* alias for right side */ - tmpy = b->dp + iy; - - /* alias for the columns of output. Offset to be equal to or above the - * smallest digit place requested + /* this is the number of times the loop will iterrate, essentially its + while (tx++ < a->used && ty-- >= 0) { ... } */ - _W = W + digs; - - /* skip cases below zero where ix > digs */ - if (iy < 0) { - iy = abs(iy); - tmpy += iy; - _W += iy; - iy = 0; + iy = MIN(a->used-tx, ty+1); + + /* execute loop */ + for (iz = 0; iz < iy; iz++) { + _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--); } - /* compute column products for digits above the minimum */ - for (; iy < pb; iy++) { -#ifndef LTMSSE - *_W++ += ((mp_word) tmpx) * ((mp_word)*tmpy++); -#else -// SSE version - asm ("movd (%0), %%mm1 \n\t" // load right side - "pmuludq %%mm0,%%mm1 \n\t" // multiply into left side - "paddq (%1),%%mm1 \n\t" // add 64-bit result out - "movq %%mm1,(%1)" // store result - :: "r"(tmpy), "r"(_W)); - // update pointers - ++tmpy; - ++_W; -#endif - } + /* store term */ + W[ix] = ((mp_digit)_W) & MP_MASK; - } + /* make next carry */ + _W = _W >> ((mp_word)DIGIT_BIT); } /* setup dest */ - oldused = c->used; - c->used = newused; + olduse = c->used; + c->used = pa; - /* now convert the array W downto what we need - * - * See comments in bn_fast_s_mp_mul_digs.c - */ -#ifdef LTMSSE - // mm2 has W[ix-1] - asm("movq (%0),%%mm2"::"r"(W + digs)); -#endif + { + register mp_digit *tmpc; - for (ix = digs + 1; ix < newused; ix++) { - /* forward the carry from the previous temp */ -#ifndef LTMSSE - W[ix] += (W[ix - 1] >> ((mp_word) DIGIT_BIT)); - c->dp[ix - 1] = (mp_digit) (W[ix - 1] & ((mp_word) MP_MASK)); -#else - asm( - "movd %%mm2,%%eax \n\t" // get 32-bit version of it W[ix-1] - "psrlq $28,%%mm2 \n\t" // W[ix-1] >> DIGIT_BIT ... must be 28 - "andl $268435455,%%eax \n\t" // & with MP_MASK against W[ix-1] - "paddq (%0),%%mm2 \n\t" // add them - "movl %%eax,(%1) \n\t" // store it - :: "r"(&W[ix]), "r"(&c->dp[ix-1]) : "%eax"); -#endif + tmpc = c->dp + digs; + for (ix = digs; ix <= pa; ix++) { + /* now extract the previous digit [below the carry] */ + *tmpc++ = W[ix]; + } + /* clear unused digits [that existed in the old copy of c] */ + for (; ix < olduse; ix++) { + *tmpc++ = 0; + } } - -#ifndef LTMSSE - c->dp[newused - 1] = (mp_digit) (W[newused - 1] & ((mp_word) MP_MASK)); -#else - // get last since we don't store into W[ix] anymore ;-) - asm("movd %%mm2,%%eax\n\t" - "andl $268435455,%%eax \n\t" // & with MP_MASK against W[ix-1] - "movl %%eax,(%0)" // store it - ::"r"(&(c->dp[newused-1])):"%eax"); -#endif - - for (; ix < oldused; ix++) { - c->dp[ix] = 0; - } - -#ifdef LTMSSE - asm("emms"); -#endif - mp_clamp (c); return MP_OKAY; } +#endif /* End: bn_fast_s_mp_mul_high_digs.c */ /* Start: bn_fast_s_mp_sqr.c */ +#include +#ifdef BN_FAST_S_MP_SQR_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -754,7 +590,6 @@ fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* fast squaring * @@ -773,182 +608,107 @@ fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs) * Based on Algorithm 14.16 on pp.597 of HAC. * */ +/* the jist of squaring... + +you do like mult except the offset of the tmpx [one that starts closer to zero] +can't equal the offset of tmpy. So basically you set up iy like before then you min it with +(ty-tx) so that it never happens. You double all those you add in the inner loop + +After that loop you do the squares and add them in. + +Remove W2 and don't memset W + +*/ + int fast_s_mp_sqr (mp_int * a, mp_int * b) { - int olduse, newused, res, ix, pa; - mp_word W2[MP_WARRAY], W[MP_WARRAY]; + int olduse, res, pa, ix, iz; + mp_digit W[MP_WARRAY], *tmpx; + mp_word W1; - /* calculate size of product and allocate as required */ - pa = a->used; - newused = pa + pa; - if (b->alloc < newused) { - if ((res = mp_grow (b, newused)) != MP_OKAY) { + /* grow the destination as required */ + pa = a->used + a->used; + if (b->alloc < pa) { + if ((res = mp_grow (b, pa)) != MP_OKAY) { return res; } } - /* zero temp buffer (columns) - * Note that there are two buffers. Since squaring requires - * a outer and inner product and the inner product requires - * computing a product and doubling it (a relatively expensive - * op to perform n**2 times if you don't have to) the inner and - * outer products are computed in different buffers. This way - * the inner product can be doubled using n doublings instead of - * n**2 - */ - memset (W, 0, newused * sizeof (mp_word)); -#ifndef LTMSSE - memset (W2, 0, newused * sizeof (mp_word)); -#endif + /* number of output digits to produce */ + W1 = 0; + for (ix = 0; ix <= pa; ix++) { + int tx, ty, iy; + mp_word _W; + mp_digit *tmpy; - /* This computes the inner product. To simplify the inner N**2 loop - * the multiplication by two is done afterwards in the N loop. - */ + /* clear counter */ + _W = 0; - for (ix = 0; ix < pa; ix++) { - /* compute the outer product - * - * Note that every outer product is computed - * for a particular column only once which means that - * there is no need todo a double precision addition - * into the W2[] array. - */ -#ifndef LTMSSE - W2[ix + ix] = ((mp_word)a->dp[ix]) * ((mp_word)a->dp[ix]); -#else - asm("movd %0,%%xmm0 \n\t" // load a->dp[ix] - "movdq2q %%xmm0,%%mm0 \n\t" // get 64-bit version - "pmuludq %%xmm0,%%xmm0 \n\t" // square it - "movdqu %%xmm0,(%1) \n\t" // store it (8-byte result, 8-byte zero) - ::"r"(a->dp[ix]), "r"(&(W2[ix+ix]))); -#endif + /* get offsets into the two bignums */ + ty = MIN(a->used-1, ix); + tx = ix - ty; - { -#ifndef LTMSSE - register mp_digit tmpx; -#endif - register mp_digit *tmpy; - register mp_word *_W; - register int iy; + /* setup temp aliases */ + tmpx = a->dp + tx; + tmpy = a->dp + ty; - /* copy of left side */ -#ifndef LTMSSE - tmpx = a->dp[ix]; -#else -//SSE we load tmpx into mm0 [note: loaded above] -// asm (" movd %0, %%mm0 " :: "r"(a->dp[ix])); -#endif + /* this is the number of times the loop will iterrate, essentially its + while (tx++ < a->used && ty-- >= 0) { ... } + */ + iy = MIN(a->used-tx, ty+1); - /* alias for right side */ - tmpy = a->dp + (ix + 1); + /* now for squaring tx can never equal ty + * we halve the distance since they approach at a rate of 2x + * and we have to round because odd cases need to be executed + */ + iy = MIN(iy, (ty-tx+1)>>1); - /* the column to store the result in */ - _W = W + (ix + ix + 1); - - /* inner products */ - for (iy = ix + 1; iy < pa; iy++) { -#ifndef LTMSSE - *_W++ += ((mp_word)tmpx) * ((mp_word)*tmpy++); -#else -// SSE version - asm ("movd (%0), %%mm1 \n\t" // load right side - "pmuludq %%mm0,%%mm1 \n\t" // multiply into left side - "paddq (%1),%%mm1 \n\t" // add 64-bit result out - "movq %%mm1,(%1)" // store result - :: "r"(tmpy), "r"(_W)); - // update pointers - ++tmpy; - ++_W; -#endif + /* execute loop */ + for (iz = 0; iz < iy; iz++) { + _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--); } - } + + /* double the inner product and add carry */ + _W = _W + _W + W1; + + /* even columns have the square term in them */ + if ((ix&1) == 0) { + _W += ((mp_word)a->dp[ix>>1])*((mp_word)a->dp[ix>>1]); + } + + /* store it */ + W[ix] = _W; + + /* make next carry */ + W1 = _W >> ((mp_word)DIGIT_BIT); } /* setup dest */ olduse = b->used; - b->used = newused; + b->used = a->used+a->used; - /* now compute digits - * - * We have to double the inner product sums, add in the - * outer product sums, propagate carries and convert - * to single precision. - */ { - register mp_digit *tmpb; - - /* double first value, since the inner products are - * half of what they should be - */ + mp_digit *tmpb; tmpb = b->dp; -#ifndef LTMSSE - W[0] += W[0] + W2[0]; -#else - // mm2 has W[ix-1] - asm("movq (%0),%%mm2 \n\t" // load W[0] - "paddq %%mm2,%%mm2 \n\t" // W[0] + W[0] - "paddq (%1),%%mm2 \n\t" // W[0] + W[0] + W2[0] - ::"r"(W),"r"(W2)); -#endif - - for (ix = 1; ix < newused; ix++) { -#ifndef LTMSSE - /* double/add next digit */ - W[ix] += W[ix] + W2[ix]; - - /* propagate carry forwards [from the previous digit] */ - W[ix] = W[ix] + (W[ix - 1] >> ((mp_word) DIGIT_BIT)); - - /* store the current digit now that the carry isn't - * needed - */ - *tmpb++ = (mp_digit) (W[ix - 1] & ((mp_word) MP_MASK)); -#else - asm( "movq (%0),%%mm0 \n\t" // load W[ix] - "movd %%mm2,%%eax \n\t" // 32-bit version of W[ix-1] - "paddq %%mm0,%%mm0 \n\t" // W[ix] + W[ix] - "psrlq $28,%%mm2 \n\t" // W[ix-1] >> DIGIT_BIT ... must be 28 - "paddq (%1),%%mm0 \n\t" // W[ix] + W[ix] + W2[ix] - "andl $268435455,%%eax \n\t" // & with MP_MASK against W[ix-1] - "paddq %%mm0,%%mm2 \n\t" // W[ix] + W[ix] + W2[ix] + W[ix-1]>>DIGIT_BIT - "movl %%eax,(%2) " // store it - :: "r"(&W[ix]), "r"(&W2[ix]), "r"(tmpb):"%eax"); - ++tmpb; -#endif + for (ix = 0; ix < pa; ix++) { + *tmpb++ = W[ix] & MP_MASK; } -#ifndef LTMSSE - /* set the last value. Note even if the carry is zero - * this is required since the next step will not zero - * it if b originally had a value at b->dp[2*a.used] - */ - *tmpb++ = (mp_digit) (W[(newused) - 1] & ((mp_word) MP_MASK)); -#else - // get last since we don't store into W[ix] anymore ;-) - asm("movd %%mm2,%%eax \n\t" - "andl $268435455,%%eax \n\t" // & with MP_MASK against W[ix-1] - "movl %%eax,(%0) " // store it - ::"r"(tmpb):"%eax"); - ++tmpb; -#endif - - /* clear high digits of b if there were any originally */ + /* clear unused digits [that existed in the old copy of c] */ for (; ix < olduse; ix++) { *tmpb++ = 0; } } - -#ifdef LTMSSE - asm("emms"); -#endif - mp_clamp (b); return MP_OKAY; } +#endif /* End: bn_fast_s_mp_sqr.c */ /* Start: bn_mp_2expt.c */ +#include +#ifdef BN_MP_2EXPT_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -963,7 +723,6 @@ int fast_s_mp_sqr (mp_int * a, mp_int * b) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* computes a = 2**b * @@ -987,14 +746,17 @@ mp_2expt (mp_int * a, int b) a->used = b / DIGIT_BIT + 1; /* put the single bit in its place */ - a->dp[b / DIGIT_BIT] = 1 << (b % DIGIT_BIT); + a->dp[b / DIGIT_BIT] = ((mp_digit)1) << (b % DIGIT_BIT); return MP_OKAY; } +#endif /* End: bn_mp_2expt.c */ /* Start: bn_mp_abs.c */ +#include +#ifdef BN_MP_ABS_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -1009,7 +771,6 @@ mp_2expt (mp_int * a, int b) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* b = |a| * @@ -1032,10 +793,13 @@ mp_abs (mp_int * a, mp_int * b) return MP_OKAY; } +#endif /* End: bn_mp_abs.c */ /* Start: bn_mp_add.c */ +#include +#ifdef BN_MP_ADD_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -1050,7 +814,6 @@ mp_abs (mp_int * a, mp_int * b) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* high level addition (handles signs) */ int mp_add (mp_int * a, mp_int * b, mp_int * c) @@ -1083,10 +846,13 @@ int mp_add (mp_int * a, mp_int * b, mp_int * c) return res; } +#endif /* End: bn_mp_add.c */ /* Start: bn_mp_add_d.c */ +#include +#ifdef BN_MP_ADD_D_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -1101,7 +867,6 @@ int mp_add (mp_int * a, mp_int * b, mp_int * c) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* single digit addition */ int @@ -1190,10 +955,13 @@ mp_add_d (mp_int * a, mp_digit b, mp_int * c) return MP_OKAY; } +#endif /* End: bn_mp_add_d.c */ /* Start: bn_mp_addmod.c */ +#include +#ifdef BN_MP_ADDMOD_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -1208,7 +976,6 @@ mp_add_d (mp_int * a, mp_digit b, mp_int * c) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* d = a + b (mod c) */ int @@ -1229,10 +996,13 @@ mp_addmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d) mp_clear (&t); return res; } +#endif /* End: bn_mp_addmod.c */ /* Start: bn_mp_and.c */ +#include +#ifdef BN_MP_AND_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -1247,7 +1017,6 @@ mp_addmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* AND two ints together */ int @@ -1284,10 +1053,13 @@ mp_and (mp_int * a, mp_int * b, mp_int * c) mp_clear (&t); return MP_OKAY; } +#endif /* End: bn_mp_and.c */ /* Start: bn_mp_clamp.c */ +#include +#ifdef BN_MP_CLAMP_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -1302,7 +1074,6 @@ mp_and (mp_int * a, mp_int * b, mp_int * c) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* trim unused digits * @@ -1326,10 +1097,13 @@ mp_clamp (mp_int * a) a->sign = MP_ZPOS; } } +#endif /* End: bn_mp_clamp.c */ /* Start: bn_mp_clear.c */ +#include +#ifdef BN_MP_CLEAR_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -1344,7 +1118,6 @@ mp_clamp (mp_int * a) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* clear one (frees) */ void @@ -1368,10 +1141,13 @@ mp_clear (mp_int * a) a->sign = MP_ZPOS; } } +#endif /* End: bn_mp_clear.c */ /* Start: bn_mp_clear_multi.c */ +#include +#ifdef BN_MP_CLEAR_MULTI_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -1386,7 +1162,6 @@ mp_clear (mp_int * a) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include #include void mp_clear_multi(mp_int *mp, ...) @@ -1400,10 +1175,13 @@ void mp_clear_multi(mp_int *mp, ...) } va_end(args); } +#endif /* End: bn_mp_clear_multi.c */ /* Start: bn_mp_cmp.c */ +#include +#ifdef BN_MP_CMP_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -1418,7 +1196,6 @@ void mp_clear_multi(mp_int *mp, ...) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* compare two ints (signed)*/ int @@ -1441,10 +1218,13 @@ mp_cmp (mp_int * a, mp_int * b) return mp_cmp_mag(a, b); } } +#endif /* End: bn_mp_cmp.c */ /* Start: bn_mp_cmp_d.c */ +#include +#ifdef BN_MP_CMP_D_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -1459,7 +1239,6 @@ mp_cmp (mp_int * a, mp_int * b) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* compare a digit */ int mp_cmp_d(mp_int * a, mp_digit b) @@ -1483,10 +1262,13 @@ int mp_cmp_d(mp_int * a, mp_digit b) return MP_EQ; } } +#endif /* End: bn_mp_cmp_d.c */ /* Start: bn_mp_cmp_mag.c */ +#include +#ifdef BN_MP_CMP_MAG_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -1501,7 +1283,6 @@ int mp_cmp_d(mp_int * a, mp_digit b) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* compare maginitude of two ints (unsigned) */ int mp_cmp_mag (mp_int * a, mp_int * b) @@ -1536,10 +1317,13 @@ int mp_cmp_mag (mp_int * a, mp_int * b) } return MP_EQ; } +#endif /* End: bn_mp_cmp_mag.c */ /* Start: bn_mp_cnt_lsb.c */ +#include +#ifdef BN_MP_CNT_LSB_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -1554,7 +1338,6 @@ int mp_cmp_mag (mp_int * a, mp_int * b) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include static const int lnz[16] = { 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 @@ -1587,10 +1370,13 @@ int mp_cnt_lsb(mp_int *a) return x; } +#endif /* End: bn_mp_cnt_lsb.c */ /* Start: bn_mp_copy.c */ +#include +#ifdef BN_MP_COPY_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -1605,7 +1391,6 @@ int mp_cnt_lsb(mp_int *a) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* copy, b = a */ int @@ -1653,10 +1438,13 @@ mp_copy (mp_int * a, mp_int * b) b->sign = a->sign; return MP_OKAY; } +#endif /* End: bn_mp_copy.c */ /* Start: bn_mp_count_bits.c */ +#include +#ifdef BN_MP_COUNT_BITS_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -1671,7 +1459,6 @@ mp_copy (mp_int * a, mp_int * b) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* returns the number of bits in an int */ int @@ -1696,10 +1483,13 @@ mp_count_bits (mp_int * a) } return r; } +#endif /* End: bn_mp_count_bits.c */ /* Start: bn_mp_div.c */ +#include +#ifdef BN_MP_DIV_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -1714,7 +1504,78 @@ mp_count_bits (mp_int * a) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include + +#ifdef BN_MP_DIV_SMALL + +/* slower bit-bang division... also smaller */ +int mp_div(mp_int * a, mp_int * b, mp_int * c, mp_int * d) +{ + mp_int ta, tb, tq, q; + int res, n, n2; + + /* is divisor zero ? */ + if (mp_iszero (b) == 1) { + return MP_VAL; + } + + /* if a < b then q=0, r = a */ + if (mp_cmp_mag (a, b) == MP_LT) { + if (d != NULL) { + res = mp_copy (a, d); + } else { + res = MP_OKAY; + } + if (c != NULL) { + mp_zero (c); + } + return res; + } + + /* init our temps */ + if ((res = mp_init_multi(&ta, &tb, &tq, &q, NULL) != MP_OKAY)) { + return res; + } + + + mp_set(&tq, 1); + n = mp_count_bits(a) - mp_count_bits(b); + if (((res = mp_copy(a, &ta)) != MP_OKAY) || + ((res = mp_copy(b, &tb)) != MP_OKAY) || + ((res = mp_mul_2d(&tb, n, &tb)) != MP_OKAY) || + ((res = mp_mul_2d(&tq, n, &tq)) != MP_OKAY)) { + goto __ERR; + } + + while (n-- >= 0) { + if (mp_cmp(&tb, &ta) != MP_GT) { + if (((res = mp_sub(&ta, &tb, &ta)) != MP_OKAY) || + ((res = mp_add(&q, &tq, &q)) != MP_OKAY)) { + goto __ERR; + } + } + if (((res = mp_div_2d(&tb, 1, &tb, NULL)) != MP_OKAY) || + ((res = mp_div_2d(&tq, 1, &tq, NULL)) != MP_OKAY)) { + goto __ERR; + } + } + + /* now q == quotient and ta == remainder */ + n = a->sign; + n2 = (a->sign == b->sign ? MP_ZPOS : MP_NEG); + if (c != NULL) { + mp_exch(c, &q); + c->sign = n2; + } + if (d != NULL) { + mp_exch(d, &ta); + d->sign = n; + } +__ERR: + mp_clear_multi(&ta, &tb, &tq, &q, NULL); + return res; +} + +#else /* integer signed division. * c*b + d == a [e.g. a/b, c=quotient, d=remainder] @@ -1889,7 +1750,7 @@ int mp_div (mp_int * a, mp_int * b, mp_int * c, mp_int * d) */ /* get sign before writing to c */ - x.sign = a->sign; + x.sign = x.used == 0 ? MP_ZPOS : a->sign; if (c != NULL) { mp_clamp (&q); @@ -1912,9 +1773,15 @@ __Q:mp_clear (&q); return res; } +#endif + +#endif + /* End: bn_mp_div.c */ /* Start: bn_mp_div_2.c */ +#include +#ifdef BN_MP_DIV_2_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -1929,7 +1796,6 @@ __Q:mp_clear (&q); * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* b = a/2 */ int mp_div_2(mp_int * a, mp_int * b) @@ -1977,10 +1843,13 @@ int mp_div_2(mp_int * a, mp_int * b) mp_clamp (b); return MP_OKAY; } +#endif /* End: bn_mp_div_2.c */ /* Start: bn_mp_div_2d.c */ +#include +#ifdef BN_MP_DIV_2D_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -1995,7 +1864,6 @@ int mp_div_2(mp_int * a, mp_int * b) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* shift right by a certain bit count (store quotient in c, optional remainder in d) */ int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d) @@ -2072,10 +1940,13 @@ int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d) mp_clear (&t); return MP_OKAY; } +#endif /* End: bn_mp_div_2d.c */ /* Start: bn_mp_div_3.c */ +#include +#ifdef BN_MP_DIV_3_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -2090,7 +1961,6 @@ int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* divide by three (based on routine from MPI and the GMP manual) */ int @@ -2149,10 +2019,13 @@ mp_div_3 (mp_int * a, mp_int *c, mp_digit * d) return res; } +#endif /* End: bn_mp_div_3.c */ /* Start: bn_mp_div_d.c */ +#include +#ifdef BN_MP_DIV_D_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -2167,7 +2040,6 @@ mp_div_3 (mp_int * a, mp_int *c, mp_digit * d) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include static int s_is_power_of_two(mp_digit b, int *p) { @@ -2209,7 +2081,7 @@ int mp_div_d (mp_int * a, mp_digit b, mp_int * c, mp_digit * d) /* power of two ? */ if (s_is_power_of_two(b, &ix) == 1) { if (d != NULL) { - *d = a->dp[0] & ((1<dp[0] & ((((mp_digit)1)<used)) != MP_OKAY) { @@ -2255,10 +2129,13 @@ int mp_div_d (mp_int * a, mp_digit b, mp_int * c, mp_digit * d) return res; } +#endif /* End: bn_mp_div_d.c */ /* Start: bn_mp_dr_is_modulus.c */ +#include +#ifdef BN_MP_DR_IS_MODULUS_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -2273,7 +2150,6 @@ int mp_div_d (mp_int * a, mp_digit b, mp_int * c, mp_digit * d) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* determines if a number is a valid DR modulus */ int mp_dr_is_modulus(mp_int *a) @@ -2296,10 +2172,13 @@ int mp_dr_is_modulus(mp_int *a) return 1; } +#endif /* End: bn_mp_dr_is_modulus.c */ /* Start: bn_mp_dr_reduce.c */ +#include +#ifdef BN_MP_DR_REDUCE_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -2314,7 +2193,6 @@ int mp_dr_is_modulus(mp_int *a) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* reduce "x" in place modulo "n" using the Diminished Radix algorithm. * @@ -2388,10 +2266,13 @@ top: } return MP_OKAY; } +#endif /* End: bn_mp_dr_reduce.c */ /* Start: bn_mp_dr_setup.c */ +#include +#ifdef BN_MP_DR_SETUP_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -2406,7 +2287,6 @@ top: * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* determines the setup value */ void mp_dr_setup(mp_int *a, mp_digit *d) @@ -2418,10 +2298,13 @@ void mp_dr_setup(mp_int *a, mp_digit *d) ((mp_word)a->dp[0])); } +#endif /* End: bn_mp_dr_setup.c */ /* Start: bn_mp_exch.c */ +#include +#ifdef BN_MP_EXCH_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -2436,7 +2319,6 @@ void mp_dr_setup(mp_int *a, mp_digit *d) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* swap the elements of two integers, for cases where you can't simply swap the * mp_int pointers around @@ -2450,10 +2332,13 @@ mp_exch (mp_int * a, mp_int * b) *a = *b; *b = t; } +#endif /* End: bn_mp_exch.c */ /* Start: bn_mp_expt_d.c */ +#include +#ifdef BN_MP_EXPT_D_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -2468,7 +2353,6 @@ mp_exch (mp_int * a, mp_int * b) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* calculate c = a**b using a square-multiply algorithm */ int mp_expt_d (mp_int * a, mp_digit b, mp_int * c) @@ -2505,10 +2389,13 @@ int mp_expt_d (mp_int * a, mp_digit b, mp_int * c) mp_clear (&g); return MP_OKAY; } +#endif /* End: bn_mp_expt_d.c */ /* Start: bn_mp_exptmod.c */ +#include +#ifdef BN_MP_EXPTMOD_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -2523,7 +2410,6 @@ int mp_expt_d (mp_int * a, mp_digit b, mp_int * c) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* this is a shell function that calls either the normal or Montgomery @@ -2542,6 +2428,7 @@ int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) /* if exponent X is negative we have to recurse */ if (X->sign == MP_NEG) { +#ifdef BN_MP_INVMOD_C mp_int tmpG, tmpX; int err; @@ -2568,29 +2455,51 @@ int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) err = mp_exptmod(&tmpG, &tmpX, P, Y); mp_clear_multi(&tmpG, &tmpX, NULL); return err; +#else + /* no invmod */ + return MP_VAL +#endif } +#ifdef BN_MP_DR_IS_MODULUS_C /* is it a DR modulus? */ dr = mp_dr_is_modulus(P); +#else + dr = 0; +#endif +#ifdef BN_MP_REDUCE_IS_2K_C /* if not, is it a uDR modulus? */ if (dr == 0) { dr = mp_reduce_is_2k(P) << 1; } +#endif /* if the modulus is odd or dr != 0 use the fast method */ +#ifdef BN_MP_EXPTMOD_FAST_C if (mp_isodd (P) == 1 || dr != 0) { return mp_exptmod_fast (G, X, P, Y, dr); } else { +#endif +#ifdef BN_S_MP_EXPTMOD_C /* otherwise use the generic Barrett reduction technique */ return s_mp_exptmod (G, X, P, Y); +#else + /* no exptmod for evens */ + return MP_VAL; +#endif +#ifdef BN_MP_EXPTMOD_FAST_C } +#endif } +#endif /* End: bn_mp_exptmod.c */ /* Start: bn_mp_exptmod_fast.c */ +#include +#ifdef BN_MP_EXPTMOD_FAST_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -2605,7 +2514,6 @@ int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* computes Y == G**X mod P, HAC pp.616, Algorithm 14.85 * @@ -2677,29 +2585,52 @@ mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) /* determine and setup reduction code */ if (redmode == 0) { +#ifdef BN_MP_MONTGOMERY_SETUP_C /* now setup montgomery */ if ((err = mp_montgomery_setup (P, &mp)) != MP_OKAY) { goto __M; } +#else + err = MP_VAL; + goto __M; +#endif /* automatically pick the comba one if available (saves quite a few calls/ifs) */ +#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C if (((P->used * 2 + 1) < MP_WARRAY) && P->used < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { redux = fast_mp_montgomery_reduce; - } else { + } else +#endif + { +#ifdef BN_MP_MONTGOMERY_REDUCE_C /* use slower baseline Montgomery method */ redux = mp_montgomery_reduce; +#else + err = MP_VAL; + goto __M; +#endif } } else if (redmode == 1) { +#if defined(BN_MP_DR_SETUP_C) && defined(BN_MP_DR_REDUCE_C) /* setup DR reduction for moduli of the form B**k - b */ mp_dr_setup(P, &mp); redux = mp_dr_reduce; +#else + err = MP_VAL; + goto __M; +#endif } else { +#if defined(BN_MP_REDUCE_2K_SETUP_C) && defined(BN_MP_REDUCE_2K_C) /* setup DR reduction for moduli of the form 2**k - b */ if ((err = mp_reduce_2k_setup(P, &mp)) != MP_OKAY) { goto __M; } redux = mp_reduce_2k; +#else + err = MP_VAL; + goto __M; +#endif } /* setup result */ @@ -2709,16 +2640,21 @@ mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) /* create M table * - * The M table contains powers of the input base, e.g. M[x] = G^x mod P + * * The first half of the table is not computed though accept for M[0] and M[1] */ if (redmode == 0) { +#ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_C /* now we need R mod m */ if ((err = mp_montgomery_calc_normalization (&res, P)) != MP_OKAY) { goto __RES; } +#else + err = MP_VAL; + goto __RES; +#endif /* now set M[1] to G * R mod m */ if ((err = mp_mulmod (G, &res, P, &M[1])) != MP_OKAY) { @@ -2862,7 +2798,7 @@ mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) * to reduce one more time to cancel out the factor * of R. */ - if ((err = mp_montgomery_reduce (&res, P, mp)) != MP_OKAY) { + if ((err = redux(&res, P, mp)) != MP_OKAY) { goto __RES; } } @@ -2878,10 +2814,14 @@ __M: } return err; } +#endif + /* End: bn_mp_exptmod_fast.c */ /* Start: bn_mp_exteuclid.c */ +#include +#ifdef BN_MP_EXTEUCLID_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -2896,7 +2836,6 @@ __M: * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* Extended euclidean algorithm of (a, b) produces a*u1 + b*u2 = u3 @@ -2951,10 +2890,13 @@ int mp_exteuclid(mp_int *a, mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3) _ERR: mp_clear_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL); return err; } +#endif /* End: bn_mp_exteuclid.c */ /* Start: bn_mp_fread.c */ +#include +#ifdef BN_MP_FREAD_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -2969,7 +2911,6 @@ _ERR: mp_clear_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* read a bigint from a file stream in ASCII */ int mp_fread(mp_int *a, int radix, FILE *stream) @@ -3016,10 +2957,13 @@ int mp_fread(mp_int *a, int radix, FILE *stream) return MP_OKAY; } +#endif /* End: bn_mp_fread.c */ /* Start: bn_mp_fwrite.c */ +#include +#ifdef BN_MP_FWRITE_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -3034,7 +2978,6 @@ int mp_fread(mp_int *a, int radix, FILE *stream) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include int mp_fwrite(mp_int *a, int radix, FILE *stream) { @@ -3066,10 +3009,13 @@ int mp_fwrite(mp_int *a, int radix, FILE *stream) return MP_OKAY; } +#endif /* End: bn_mp_fwrite.c */ /* Start: bn_mp_gcd.c */ +#include +#ifdef BN_MP_GCD_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -3084,7 +3030,6 @@ int mp_fwrite(mp_int *a, int radix, FILE *stream) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* Greatest Common Divisor using the binary method */ int mp_gcd (mp_int * a, mp_int * b, mp_int * c) @@ -3177,10 +3122,13 @@ __V:mp_clear (&u); __U:mp_clear (&v); return res; } +#endif /* End: bn_mp_gcd.c */ /* Start: bn_mp_get_int.c */ +#include +#ifdef BN_MP_GET_INT_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -3195,7 +3143,6 @@ __U:mp_clear (&v); * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* get the lower 32-bits of an mp_int */ unsigned long mp_get_int(mp_int * a) @@ -3220,10 +3167,13 @@ unsigned long mp_get_int(mp_int * a) /* force result to 32-bits always so it is consistent on non 32-bit platforms */ return res & 0xFFFFFFFFUL; } +#endif /* End: bn_mp_get_int.c */ /* Start: bn_mp_grow.c */ +#include +#ifdef BN_MP_GROW_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -3238,7 +3188,6 @@ unsigned long mp_get_int(mp_int * a) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* grow as required */ int mp_grow (mp_int * a, int size) @@ -3275,10 +3224,13 @@ int mp_grow (mp_int * a, int size) } return MP_OKAY; } +#endif /* End: bn_mp_grow.c */ /* Start: bn_mp_init.c */ +#include +#ifdef BN_MP_INIT_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -3293,7 +3245,6 @@ int mp_grow (mp_int * a, int size) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* init a new mp_int */ int mp_init (mp_int * a) @@ -3319,10 +3270,13 @@ int mp_init (mp_int * a) return MP_OKAY; } +#endif /* End: bn_mp_init.c */ /* Start: bn_mp_init_copy.c */ +#include +#ifdef BN_MP_INIT_COPY_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -3337,7 +3291,6 @@ int mp_init (mp_int * a) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* creates "a" then copies b into it */ int mp_init_copy (mp_int * a, mp_int * b) @@ -3349,10 +3302,13 @@ int mp_init_copy (mp_int * a, mp_int * b) } return mp_copy (b, a); } +#endif /* End: bn_mp_init_copy.c */ /* Start: bn_mp_init_multi.c */ +#include +#ifdef BN_MP_INIT_MULTI_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -3367,7 +3323,6 @@ int mp_init_copy (mp_int * a, mp_int * b) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include #include int mp_init_multi(mp_int *mp, ...) @@ -3406,10 +3361,13 @@ int mp_init_multi(mp_int *mp, ...) return res; /* Assumed ok, if error flagged above. */ } +#endif /* End: bn_mp_init_multi.c */ /* Start: bn_mp_init_set.c */ +#include +#ifdef BN_MP_INIT_SET_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -3424,7 +3382,6 @@ int mp_init_multi(mp_int *mp, ...) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* initialize and set a digit */ int mp_init_set (mp_int * a, mp_digit b) @@ -3436,10 +3393,13 @@ int mp_init_set (mp_int * a, mp_digit b) mp_set(a, b); return err; } +#endif /* End: bn_mp_init_set.c */ /* Start: bn_mp_init_set_int.c */ +#include +#ifdef BN_MP_INIT_SET_INT_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -3454,7 +3414,6 @@ int mp_init_set (mp_int * a, mp_digit b) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* initialize and set a digit */ int mp_init_set_int (mp_int * a, unsigned long b) @@ -3465,10 +3424,13 @@ int mp_init_set_int (mp_int * a, unsigned long b) } return mp_set_int(a, b); } +#endif /* End: bn_mp_init_set_int.c */ /* Start: bn_mp_init_size.c */ +#include +#ifdef BN_MP_INIT_SIZE_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -3483,29 +3445,40 @@ int mp_init_set_int (mp_int * a, unsigned long b) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* init an mp_init for a given size */ int mp_init_size (mp_int * a, int size) { + int x; + /* pad size so there are always extra digits */ size += (MP_PREC * 2) - (size % MP_PREC); /* alloc mem */ - a->dp = OPT_CAST(mp_digit) XCALLOC (sizeof (mp_digit), size); + a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * size); if (a->dp == NULL) { return MP_MEM; } + + /* set the members */ a->used = 0; a->alloc = size; a->sign = MP_ZPOS; + /* zero the digits */ + for (x = 0; x < size; x++) { + a->dp[x] = 0; + } + return MP_OKAY; } +#endif /* End: bn_mp_init_size.c */ /* Start: bn_mp_invmod.c */ +#include +#ifdef BN_MP_INVMOD_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -3520,10 +3493,52 @@ int mp_init_size (mp_int * a, int size) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* hac 14.61, pp608 */ int mp_invmod (mp_int * a, mp_int * b, mp_int * c) +{ + /* b cannot be negative */ + if (b->sign == MP_NEG || mp_iszero(b) == 1) { + return MP_VAL; + } + +#ifdef BN_FAST_MP_INVMOD_C + /* if the modulus is odd we can use a faster routine instead */ + if (mp_isodd (b) == 1) { + return fast_mp_invmod (a, b, c); + } +#endif + +#ifdef BN_MP_INVMOD_SLOW_C + return mp_invmod_slow(a, b, c); +#endif + + return MP_VAL; +} +#endif + +/* End: bn_mp_invmod.c */ + +/* Start: bn_mp_invmod_slow.c */ +#include +#ifdef BN_MP_INVMOD_SLOW_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * 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 + */ + +/* hac 14.61, pp608 */ +int mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c) { mp_int x, y, u, v, A, B, C, D; int res; @@ -3533,11 +3548,6 @@ int mp_invmod (mp_int * a, mp_int * b, mp_int * c) return MP_VAL; } - /* if the modulus is odd we can use a faster routine instead */ - if (mp_isodd (b) == 1) { - return fast_mp_invmod (a, b, c); - } - /* init temps */ if ((res = mp_init_multi(&x, &y, &u, &v, &A, &B, &C, &D, NULL)) != MP_OKAY) { @@ -3680,10 +3690,13 @@ top: __ERR:mp_clear_multi (&x, &y, &u, &v, &A, &B, &C, &D, NULL); return res; } +#endif -/* End: bn_mp_invmod.c */ +/* End: bn_mp_invmod_slow.c */ /* Start: bn_mp_is_square.c */ +#include +#ifdef BN_MP_IS_SQUARE_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -3698,7 +3711,6 @@ __ERR:mp_clear_multi (&x, &y, &u, &v, &A, &B, &C, &D, NULL); * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* Check if remainders are possible squares - fast exclude non-squares */ static const char rem_128[128] = { @@ -3755,7 +3767,7 @@ int mp_is_square(mp_int *arg,int *ret) return MP_OKAY; } - /* product of primes less than 2^31 */ + if ((res = mp_init_set_int(&t,11L*13L*17L*19L*23L*29L*31L)) != MP_OKAY) { return res; } @@ -3787,10 +3799,13 @@ int mp_is_square(mp_int *arg,int *ret) ERR:mp_clear(&t); return res; } +#endif /* End: bn_mp_is_square.c */ /* Start: bn_mp_jacobi.c */ +#include +#ifdef BN_MP_JACOBI_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -3805,7 +3820,6 @@ ERR:mp_clear(&t); * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* computes the jacobi c = (a | n) (or Legendre if n is prime) * HAC pp. 73 Algorithm 2.149 @@ -3890,10 +3904,13 @@ __P1:mp_clear (&p1); __A1:mp_clear (&a1); return res; } +#endif /* End: bn_mp_jacobi.c */ /* Start: bn_mp_karatsuba_mul.c */ +#include +#ifdef BN_MP_KARATSUBA_MUL_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -3908,7 +3925,6 @@ __A1:mp_clear (&a1); * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* c = |a| * |b| using Karatsuba Multiplication using * three half size multiplications @@ -3972,9 +3988,6 @@ int mp_karatsuba_mul (mp_int * a, mp_int * b, mp_int * c) goto X0Y0; /* now shift the digits */ - x0.sign = x1.sign = a->sign; - y0.sign = y1.sign = b->sign; - x0.used = y0.used = B; x1.used = a->used - B; y1.used = b->used - B; @@ -4058,10 +4071,13 @@ X0:mp_clear (&x0); ERR: return err; } +#endif /* End: bn_mp_karatsuba_mul.c */ /* Start: bn_mp_karatsuba_sqr.c */ +#include +#ifdef BN_MP_KARATSUBA_SQR_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -4076,12 +4092,11 @@ ERR: * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* Karatsuba squaring, computes b = a*a using three * half size squarings * - * See comments of mp_karatsuba_mul for details. It + * See comments of karatsuba_mul for details. It * is essentially the same algorithm but merely * tuned to perform recursive squarings. */ @@ -4177,10 +4192,13 @@ X0:mp_clear (&x0); ERR: return err; } +#endif /* End: bn_mp_karatsuba_sqr.c */ /* Start: bn_mp_lcm.c */ +#include +#ifdef BN_MP_LCM_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -4195,7 +4213,6 @@ ERR: * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* computes least common multiple as |a*b|/(a, b) */ int mp_lcm (mp_int * a, mp_int * b, mp_int * c) @@ -4235,10 +4252,13 @@ __T: mp_clear_multi (&t1, &t2, NULL); return res; } +#endif /* End: bn_mp_lcm.c */ /* Start: bn_mp_lshd.c */ +#include +#ifdef BN_MP_LSHD_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -4253,7 +4273,6 @@ __T: * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* shift left a certain amount of digits */ int mp_lshd (mp_int * a, int b) @@ -4300,10 +4319,13 @@ int mp_lshd (mp_int * a, int b) } return MP_OKAY; } +#endif /* End: bn_mp_lshd.c */ /* Start: bn_mp_mod.c */ +#include +#ifdef BN_MP_MOD_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -4318,7 +4340,6 @@ int mp_lshd (mp_int * a, int b) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* c = a mod b, 0 <= c < b */ int @@ -4346,10 +4367,13 @@ mp_mod (mp_int * a, mp_int * b, mp_int * c) mp_clear (&t); return res; } +#endif /* End: bn_mp_mod.c */ /* Start: bn_mp_mod_2d.c */ +#include +#ifdef BN_MP_MOD_2D_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -4364,7 +4388,6 @@ mp_mod (mp_int * a, mp_int * b, mp_int * c) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* calc a value mod 2**b */ int @@ -4399,10 +4422,13 @@ mp_mod_2d (mp_int * a, int b, mp_int * c) mp_clamp (c); return MP_OKAY; } +#endif /* End: bn_mp_mod_2d.c */ /* Start: bn_mp_mod_d.c */ +#include +#ifdef BN_MP_MOD_D_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -4417,17 +4443,19 @@ mp_mod_2d (mp_int * a, int b, mp_int * c) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include int mp_mod_d (mp_int * a, mp_digit b, mp_digit * c) { return mp_div_d(a, b, NULL, c); } +#endif /* End: bn_mp_mod_d.c */ /* Start: bn_mp_montgomery_calc_normalization.c */ +#include +#ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -4442,31 +4470,31 @@ mp_mod_d (mp_int * a, mp_digit b, mp_digit * c) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include -/* calculates a = B^n mod b for Montgomery reduction - * Where B is the base [e.g. 2^DIGIT_BIT]. - * B^n mod b is computed by first computing - * A = B^(n-1) which doesn't require a reduction but a simple OR. - * then C = A * B = B^n is computed by performing upto DIGIT_BIT +/* * shifts with subtractions when the result is greater than b. * * The method is slightly modified to shift B unconditionally upto just under * the leading bit of b. This saves alot of multiple precision shifting. */ -int -mp_montgomery_calc_normalization (mp_int * a, mp_int * b) +int mp_montgomery_calc_normalization (mp_int * a, mp_int * b) { int x, bits, res; /* how many bits of last digit does b use */ bits = mp_count_bits (b) % DIGIT_BIT; - /* compute A = B^(n-1) * 2^(bits-1) */ - if ((res = mp_2expt (a, (b->used - 1) * DIGIT_BIT + bits - 1)) != MP_OKAY) { - return res; + + if (b->used > 1) { + if ((res = mp_2expt (a, (b->used - 1) * DIGIT_BIT + bits - 1)) != MP_OKAY) { + return res; + } + } else { + mp_set(a, 1); + bits = 1; } + /* now compute C = A * B mod b */ for (x = bits - 1; x < (int)DIGIT_BIT; x++) { if ((res = mp_mul_2 (a, a)) != MP_OKAY) { @@ -4481,10 +4509,13 @@ mp_montgomery_calc_normalization (mp_int * a, mp_int * b) return MP_OKAY; } +#endif /* End: bn_mp_montgomery_calc_normalization.c */ /* Start: bn_mp_montgomery_reduce.c */ +#include +#ifdef BN_MP_MONTGOMERY_REDUCE_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -4499,7 +4530,6 @@ mp_montgomery_calc_normalization (mp_int * a, mp_int * b) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* computes xR**-1 == x (mod N) via Montgomery Reduction */ int @@ -4510,7 +4540,7 @@ mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) /* can the fast reduction [comba] method be used? * - * Note that unlike in mp_mul you're safely allowed *less* + * Note that unlike in mul you're safely allowed *less* * than the available columns [255 per default] since carries * are fixed up in the inner loop. */ @@ -4533,7 +4563,7 @@ mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) /* mu = ai * rho mod b * * The value of rho must be precalculated via - * bn_mp_montgomery_setup() such that + * montgomery_setup() such that * it equals -1/n0 mod b this allows the * following inner loop to reduce the * input one digit at a time @@ -4597,10 +4627,13 @@ mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) return MP_OKAY; } +#endif /* End: bn_mp_montgomery_reduce.c */ /* Start: bn_mp_montgomery_setup.c */ +#include +#ifdef BN_MP_MONTGOMERY_SETUP_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -4615,7 +4648,6 @@ mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* setups the montgomery reduction stuff */ int @@ -4650,14 +4682,17 @@ mp_montgomery_setup (mp_int * n, mp_digit * rho) #endif /* rho = -1/m mod b */ - *rho = (((mp_digit) 1 << ((mp_digit) DIGIT_BIT)) - x) & MP_MASK; + *rho = (((mp_word)1 << ((mp_word) DIGIT_BIT)) - x) & MP_MASK; return MP_OKAY; } +#endif /* End: bn_mp_montgomery_setup.c */ /* Start: bn_mp_mul.c */ +#include +#ifdef BN_MP_MUL_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -4672,7 +4707,6 @@ mp_montgomery_setup (mp_int * n, mp_digit * rho) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* high level multiplication (handles sign) */ int mp_mul (mp_int * a, mp_int * b, mp_int * c) @@ -4681,12 +4715,18 @@ int mp_mul (mp_int * a, mp_int * b, mp_int * c) neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG; /* use Toom-Cook? */ +#ifdef BN_MP_TOOM_MUL_C if (MIN (a->used, b->used) >= TOOM_MUL_CUTOFF) { res = mp_toom_mul(a, b, c); + } else +#endif +#ifdef BN_MP_KARATSUBA_MUL_C /* use Karatsuba? */ - } else if (MIN (a->used, b->used) >= KARATSUBA_MUL_CUTOFF) { + if (MIN (a->used, b->used) >= KARATSUBA_MUL_CUTOFF) { res = mp_karatsuba_mul (a, b, c); - } else { + } else +#endif + { /* can we use the fast multiplier? * * The fast multiplier can be used if the output will @@ -4695,21 +4735,30 @@ int mp_mul (mp_int * a, mp_int * b, mp_int * c) */ int digs = a->used + b->used + 1; +#ifdef BN_FAST_S_MP_MUL_DIGS_C if ((digs < MP_WARRAY) && MIN(a->used, b->used) <= (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { res = fast_s_mp_mul_digs (a, b, c, digs); - } else { - res = s_mp_mul (a, b, c); - } + } else +#endif +#ifdef BN_S_MP_MUL_DIGS_C + res = s_mp_mul (a, b, c); /* uses s_mp_mul_digs */ +#else + res = MP_VAL; +#endif + } - c->sign = (c->used == 0) ? MP_ZPOS : neg; + c->sign = (c->used > 0) ? neg : MP_ZPOS; return res; } +#endif /* End: bn_mp_mul.c */ /* Start: bn_mp_mul_2.c */ +#include +#ifdef BN_MP_MUL_2_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -4724,7 +4773,6 @@ int mp_mul (mp_int * a, mp_int * b, mp_int * c) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* b = a*2 */ int mp_mul_2(mp_int * a, mp_int * b) @@ -4786,10 +4834,13 @@ int mp_mul_2(mp_int * a, mp_int * b) b->sign = a->sign; return MP_OKAY; } +#endif /* End: bn_mp_mul_2.c */ /* Start: bn_mp_mul_2d.c */ +#include +#ifdef BN_MP_MUL_2D_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -4804,7 +4855,6 @@ int mp_mul_2(mp_int * a, mp_int * b) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* shift left by a certain bit count */ int mp_mul_2d (mp_int * a, int b, mp_int * c) @@ -4869,10 +4919,13 @@ int mp_mul_2d (mp_int * a, int b, mp_int * c) mp_clamp (c); return MP_OKAY; } +#endif /* End: bn_mp_mul_2d.c */ /* Start: bn_mp_mul_d.c */ +#include +#ifdef BN_MP_MUL_D_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -4887,7 +4940,6 @@ int mp_mul_2d (mp_int * a, int b, mp_int * c) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* multiply by a digit */ int @@ -4945,10 +4997,13 @@ mp_mul_d (mp_int * a, mp_digit b, mp_int * c) return MP_OKAY; } +#endif /* End: bn_mp_mul_d.c */ /* Start: bn_mp_mulmod.c */ +#include +#ifdef BN_MP_MULMOD_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -4963,7 +5018,6 @@ mp_mul_d (mp_int * a, mp_digit b, mp_int * c) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* d = a * b (mod c) */ int @@ -4984,10 +5038,13 @@ mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d) mp_clear (&t); return res; } +#endif /* End: bn_mp_mulmod.c */ /* Start: bn_mp_n_root.c */ +#include +#ifdef BN_MP_N_ROOT_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -5002,7 +5059,6 @@ mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* find the n'th root of an integer * @@ -5114,10 +5170,13 @@ __T2:mp_clear (&t2); __T1:mp_clear (&t1); return res; } +#endif /* End: bn_mp_n_root.c */ /* Start: bn_mp_neg.c */ +#include +#ifdef BN_MP_NEG_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -5132,7 +5191,6 @@ __T1:mp_clear (&t1); * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* b = -a */ int mp_neg (mp_int * a, mp_int * b) @@ -5146,10 +5204,13 @@ int mp_neg (mp_int * a, mp_int * b) } return MP_OKAY; } +#endif /* End: bn_mp_neg.c */ /* Start: bn_mp_or.c */ +#include +#ifdef BN_MP_OR_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -5164,7 +5225,6 @@ int mp_neg (mp_int * a, mp_int * b) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* OR two ints together */ int mp_or (mp_int * a, mp_int * b, mp_int * c) @@ -5194,10 +5254,13 @@ int mp_or (mp_int * a, mp_int * b, mp_int * c) mp_clear (&t); return MP_OKAY; } +#endif /* End: bn_mp_or.c */ /* Start: bn_mp_prime_fermat.c */ +#include +#ifdef BN_MP_PRIME_FERMAT_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -5212,7 +5275,6 @@ int mp_or (mp_int * a, mp_int * b, mp_int * c) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* performs one Fermat test. * @@ -5254,10 +5316,13 @@ int mp_prime_fermat (mp_int * a, mp_int * b, int *result) __T:mp_clear (&t); return err; } +#endif /* End: bn_mp_prime_fermat.c */ /* Start: bn_mp_prime_is_divisible.c */ +#include +#ifdef BN_MP_PRIME_IS_DIVISIBLE_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -5272,7 +5337,6 @@ __T:mp_clear (&t); * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* determines if an integers is divisible by one * of the first PRIME_SIZE primes or not @@ -5302,10 +5366,13 @@ int mp_prime_is_divisible (mp_int * a, int *result) return MP_OKAY; } +#endif /* End: bn_mp_prime_is_divisible.c */ /* Start: bn_mp_prime_is_prime.c */ +#include +#ifdef BN_MP_PRIME_IS_PRIME_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -5320,12 +5387,11 @@ int mp_prime_is_divisible (mp_int * a, int *result) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* performs a variable number of rounds of Miller-Rabin * * Probability of error after t rounds is no more than - * (1/4)^t when 1 <= t <= PRIME_SIZE + * * Sets result to 1 if probably prime, 0 otherwise */ @@ -5383,10 +5449,13 @@ int mp_prime_is_prime (mp_int * a, int t, int *result) __B:mp_clear (&b); return err; } +#endif /* End: bn_mp_prime_is_prime.c */ /* Start: bn_mp_prime_miller_rabin.c */ +#include +#ifdef BN_MP_PRIME_MILLER_RABIN_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -5401,7 +5470,6 @@ __B:mp_clear (&b); * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* Miller-Rabin test of "a" to the base of "b" as described in * HAC pp. 139 Algorithm 4.24 @@ -5484,10 +5552,13 @@ __R:mp_clear (&r); __N1:mp_clear (&n1); return err; } +#endif /* End: bn_mp_prime_miller_rabin.c */ /* Start: bn_mp_prime_next_prime.c */ +#include +#ifdef BN_MP_PRIME_NEXT_PRIME_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -5502,7 +5573,6 @@ __N1:mp_clear (&n1); * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* finds the next prime after the number "a" using "t" trials * of Miller-Rabin. @@ -5652,10 +5722,13 @@ __ERR: return err; } +#endif /* End: bn_mp_prime_next_prime.c */ -/* Start: bn_mp_prime_random_ex.c */ +/* Start: bn_mp_prime_rabin_miller_trials.c */ +#include +#ifdef BN_MP_PRIME_RABIN_MILLER_TRIALS_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -5670,7 +5743,58 @@ __ERR: * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ + + +static const struct { + int k, t; +} sizes[] = { +{ 128, 28 }, +{ 256, 16 }, +{ 384, 10 }, +{ 512, 7 }, +{ 640, 6 }, +{ 768, 5 }, +{ 896, 4 }, +{ 1024, 4 } +}; + +/* returns # of RM trials required for a given bit size */ +int mp_prime_rabin_miller_trials(int size) +{ + int x; + + for (x = 0; x < (int)(sizeof(sizes)/(sizeof(sizes[0]))); x++) { + if (sizes[x].k == size) { + return sizes[x].t; + } else if (sizes[x].k > size) { + return (x == 0) ? sizes[0].t : sizes[x - 1].t; + } + } + return sizes[x-1].t + 1; +} + + +#endif + +/* End: bn_mp_prime_rabin_miller_trials.c */ + +/* Start: bn_mp_prime_random_ex.c */ #include +#ifdef BN_MP_PRIME_RANDOM_EX_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * 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 + */ /* makes a truly random prime of a given size (bits), * @@ -5750,6 +5874,9 @@ int mp_prime_random_ex(mp_int *a, int t, int size, int flags, ltm_prime_callback /* is it prime? */ if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY) { goto error; } + if (res == MP_NO) { + continue; + } if (flags & LTM_PRIME_SAFE) { /* see if (a-1)/2 is prime */ @@ -5774,10 +5901,13 @@ error: } +#endif /* End: bn_mp_prime_random_ex.c */ /* Start: bn_mp_radix_size.c */ +#include +#ifdef BN_MP_RADIX_SIZE_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -5792,7 +5922,6 @@ error: * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* returns size of ASCII reprensentation */ int mp_radix_size (mp_int * a, int radix, int *size) @@ -5843,10 +5972,13 @@ int mp_radix_size (mp_int * a, int radix, int *size) return MP_OKAY; } +#endif /* End: bn_mp_radix_size.c */ /* Start: bn_mp_radix_smap.c */ +#include +#ifdef BN_MP_RADIX_SMAP_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -5861,14 +5993,16 @@ int mp_radix_size (mp_int * a, int radix, int *size) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* chars used in radix conversions */ const char *mp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/"; +#endif /* End: bn_mp_radix_smap.c */ /* Start: bn_mp_rand.c */ +#include +#ifdef BN_MP_RAND_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -5883,7 +6017,6 @@ const char *mp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrs * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* makes a pseudo-random int of a given size */ int @@ -5918,10 +6051,13 @@ mp_rand (mp_int * a, int digits) return MP_OKAY; } +#endif /* End: bn_mp_rand.c */ /* Start: bn_mp_read_radix.c */ +#include +#ifdef BN_MP_READ_RADIX_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -5936,7 +6072,6 @@ mp_rand (mp_int * a, int digits) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* read a string [ASCII] in a given radix */ int mp_read_radix (mp_int * a, char *str, int radix) @@ -5998,10 +6133,13 @@ int mp_read_radix (mp_int * a, char *str, int radix) } return MP_OKAY; } +#endif /* End: bn_mp_read_radix.c */ /* Start: bn_mp_read_signed_bin.c */ +#include +#ifdef BN_MP_READ_SIGNED_BIN_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -6016,7 +6154,6 @@ int mp_read_radix (mp_int * a, char *str, int radix) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* read signed bin, big endian, first byte is 0==positive or 1==negative */ int @@ -6038,10 +6175,13 @@ mp_read_signed_bin (mp_int * a, unsigned char *b, int c) return MP_OKAY; } +#endif /* End: bn_mp_read_signed_bin.c */ /* Start: bn_mp_read_unsigned_bin.c */ +#include +#ifdef BN_MP_READ_UNSIGNED_BIN_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -6056,7 +6196,6 @@ mp_read_signed_bin (mp_int * a, unsigned char *b, int c) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* reads a unsigned char array, assumes the msb is stored first [big endian] */ int @@ -6092,10 +6231,13 @@ mp_read_unsigned_bin (mp_int * a, unsigned char *b, int c) mp_clamp (a); return MP_OKAY; } +#endif /* End: bn_mp_read_unsigned_bin.c */ /* Start: bn_mp_reduce.c */ +#include +#ifdef BN_MP_REDUCE_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -6110,7 +6252,6 @@ mp_read_unsigned_bin (mp_int * a, unsigned char *b, int c) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* reduces x mod m, assumes 0 < x < m**2, mu is * precomputed via mp_reduce_setup. @@ -6136,9 +6277,20 @@ mp_reduce (mp_int * x, mp_int * m, mp_int * mu) goto CLEANUP; } } else { +#ifdef BN_S_MP_MUL_HIGH_DIGS_C if ((res = s_mp_mul_high_digs (&q, mu, &q, um - 1)) != MP_OKAY) { goto CLEANUP; } +#elif defined(BN_FAST_S_MP_MUL_HIGH_DIGS_C) + if ((res = fast_s_mp_mul_high_digs (&q, mu, &q, um - 1)) != MP_OKAY) { + goto CLEANUP; + } +#else + { + res = MP_VAL; + goto CLEANUP; + } +#endif } /* q3 = q2 / b**(k+1) */ @@ -6180,10 +6332,13 @@ CLEANUP: return res; } +#endif /* End: bn_mp_reduce.c */ /* Start: bn_mp_reduce_2k.c */ +#include +#ifdef BN_MP_REDUCE_2K_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -6198,7 +6353,6 @@ CLEANUP: * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* reduces a modulo n where n is of the form 2**p - d */ int @@ -6240,10 +6394,13 @@ ERR: return res; } +#endif /* End: bn_mp_reduce_2k.c */ /* Start: bn_mp_reduce_2k_setup.c */ +#include +#ifdef BN_MP_REDUCE_2K_SETUP_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -6258,7 +6415,6 @@ ERR: * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* determines the setup value */ int @@ -6286,10 +6442,13 @@ mp_reduce_2k_setup(mp_int *a, mp_digit *d) mp_clear(&tmp); return MP_OKAY; } +#endif /* End: bn_mp_reduce_2k_setup.c */ /* Start: bn_mp_reduce_is_2k.c */ +#include +#ifdef BN_MP_REDUCE_IS_2K_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -6304,12 +6463,12 @@ mp_reduce_2k_setup(mp_int *a, mp_digit *d) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* determines if mp_reduce_2k can be used */ int mp_reduce_is_2k(mp_int *a) { - int ix, iy, iz, iw; + int ix, iy, iw; + mp_digit iz; if (a->used == 0) { return 0; @@ -6326,7 +6485,7 @@ int mp_reduce_is_2k(mp_int *a) return 0; } iz <<= 1; - if (iz > (int)MP_MASK) { + if (iz > (mp_digit)MP_MASK) { ++iw; iz = 1; } @@ -6335,10 +6494,13 @@ int mp_reduce_is_2k(mp_int *a) return 1; } +#endif /* End: bn_mp_reduce_is_2k.c */ /* Start: bn_mp_reduce_setup.c */ +#include +#ifdef BN_MP_REDUCE_SETUP_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -6353,13 +6515,11 @@ int mp_reduce_is_2k(mp_int *a) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* pre-calculate the value required for Barrett reduction * For a given modulus "b" it calulates the value required in "a" */ -int -mp_reduce_setup (mp_int * a, mp_int * b) +int mp_reduce_setup (mp_int * a, mp_int * b) { int res; @@ -6368,10 +6528,13 @@ mp_reduce_setup (mp_int * a, mp_int * b) } return mp_div (a, b, a, NULL); } +#endif /* End: bn_mp_reduce_setup.c */ /* Start: bn_mp_rshd.c */ +#include +#ifdef BN_MP_RSHD_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -6386,7 +6549,6 @@ mp_reduce_setup (mp_int * a, mp_int * b) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* shift right a certain amount of digits */ void mp_rshd (mp_int * a, int b) @@ -6438,10 +6600,13 @@ void mp_rshd (mp_int * a, int b) /* remove excess digits */ a->used -= b; } +#endif /* End: bn_mp_rshd.c */ /* Start: bn_mp_set.c */ +#include +#ifdef BN_MP_SET_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -6456,7 +6621,6 @@ void mp_rshd (mp_int * a, int b) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* set to a digit */ void mp_set (mp_int * a, mp_digit b) @@ -6465,10 +6629,13 @@ void mp_set (mp_int * a, mp_digit b) a->dp[0] = b & MP_MASK; a->used = (a->dp[0] != 0) ? 1 : 0; } +#endif /* End: bn_mp_set.c */ /* Start: bn_mp_set_int.c */ +#include +#ifdef BN_MP_SET_INT_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -6483,7 +6650,6 @@ void mp_set (mp_int * a, mp_digit b) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* set a 32-bit const */ int mp_set_int (mp_int * a, unsigned long b) @@ -6511,10 +6677,13 @@ int mp_set_int (mp_int * a, unsigned long b) mp_clamp (a); return MP_OKAY; } +#endif /* End: bn_mp_set_int.c */ /* Start: bn_mp_shrink.c */ +#include +#ifdef BN_MP_SHRINK_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -6529,7 +6698,6 @@ int mp_set_int (mp_int * a, unsigned long b) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* shrink a bignum */ int mp_shrink (mp_int * a) @@ -6544,10 +6712,13 @@ int mp_shrink (mp_int * a) } return MP_OKAY; } +#endif /* End: bn_mp_shrink.c */ /* Start: bn_mp_signed_bin_size.c */ +#include +#ifdef BN_MP_SIGNED_BIN_SIZE_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -6562,17 +6733,19 @@ int mp_shrink (mp_int * a) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* get the size for an signed equivalent */ int mp_signed_bin_size (mp_int * a) { return 1 + mp_unsigned_bin_size (a); } +#endif /* End: bn_mp_signed_bin_size.c */ /* Start: bn_mp_sqr.c */ +#include +#ifdef BN_MP_SQR_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -6587,7 +6760,6 @@ int mp_signed_bin_size (mp_int * a) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* computes b = a*a */ int @@ -6595,29 +6767,43 @@ mp_sqr (mp_int * a, mp_int * b) { int res; +#ifdef BN_MP_TOOM_SQR_C /* use Toom-Cook? */ if (a->used >= TOOM_SQR_CUTOFF) { res = mp_toom_sqr(a, b); /* Karatsuba? */ - } else if (a->used >= KARATSUBA_SQR_CUTOFF) { + } else +#endif +#ifdef BN_MP_KARATSUBA_SQR_C +if (a->used >= KARATSUBA_SQR_CUTOFF) { res = mp_karatsuba_sqr (a, b); - } else { + } else +#endif + { +#ifdef BN_FAST_S_MP_SQR_C /* can we use the fast comba multiplier? */ if ((a->used * 2 + 1) < MP_WARRAY && a->used < (1 << (sizeof(mp_word) * CHAR_BIT - 2*DIGIT_BIT - 1))) { res = fast_s_mp_sqr (a, b); - } else { + } else +#endif +#ifdef BN_S_MP_SQR_C res = s_mp_sqr (a, b); - } +#else + res = MP_VAL; +#endif } b->sign = MP_ZPOS; return res; } +#endif /* End: bn_mp_sqr.c */ /* Start: bn_mp_sqrmod.c */ +#include +#ifdef BN_MP_SQRMOD_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -6632,7 +6818,6 @@ mp_sqr (mp_int * a, mp_int * b) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* c = a * a (mod b) */ int @@ -6653,10 +6838,13 @@ mp_sqrmod (mp_int * a, mp_int * b, mp_int * c) mp_clear (&t); return res; } +#endif /* End: bn_mp_sqrmod.c */ /* Start: bn_mp_sqrt.c */ +#include +#ifdef BN_MP_SQRT_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -6671,7 +6859,6 @@ mp_sqrmod (mp_int * a, mp_int * b, mp_int * c) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* this function is less generic than mp_n_root, simpler and faster */ int mp_sqrt(mp_int *arg, mp_int *ret) @@ -6732,10 +6919,13 @@ E2: mp_clear(&t1); return res; } +#endif /* End: bn_mp_sqrt.c */ /* Start: bn_mp_sub.c */ +#include +#ifdef BN_MP_SUB_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -6750,7 +6940,6 @@ E2: mp_clear(&t1); * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* high level subtraction (handles signs) */ int @@ -6789,10 +6978,13 @@ mp_sub (mp_int * a, mp_int * b, mp_int * c) return res; } +#endif /* End: bn_mp_sub.c */ /* Start: bn_mp_sub_d.c */ +#include +#ifdef BN_MP_SUB_D_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -6807,7 +6999,6 @@ mp_sub (mp_int * a, mp_int * b, mp_int * c) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* single digit subtraction */ int @@ -6876,10 +7067,13 @@ mp_sub_d (mp_int * a, mp_digit b, mp_int * c) return MP_OKAY; } +#endif /* End: bn_mp_sub_d.c */ /* Start: bn_mp_submod.c */ +#include +#ifdef BN_MP_SUBMOD_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -6894,7 +7088,6 @@ mp_sub_d (mp_int * a, mp_digit b, mp_int * c) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* d = a - b (mod c) */ int @@ -6916,10 +7109,13 @@ mp_submod (mp_int * a, mp_int * b, mp_int * c, mp_int * d) mp_clear (&t); return res; } +#endif /* End: bn_mp_submod.c */ /* Start: bn_mp_to_signed_bin.c */ +#include +#ifdef BN_MP_TO_SIGNED_BIN_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -6934,7 +7130,6 @@ mp_submod (mp_int * a, mp_int * b, mp_int * c, mp_int * d) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* store in signed [big endian] format */ int @@ -6948,10 +7143,13 @@ mp_to_signed_bin (mp_int * a, unsigned char *b) b[0] = (unsigned char) ((a->sign == MP_ZPOS) ? 0 : 1); return MP_OKAY; } +#endif /* End: bn_mp_to_signed_bin.c */ /* Start: bn_mp_to_unsigned_bin.c */ +#include +#ifdef BN_MP_TO_UNSIGNED_BIN_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -6966,7 +7164,6 @@ mp_to_signed_bin (mp_int * a, unsigned char *b) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* store in unsigned [big endian] format */ int @@ -6995,10 +7192,13 @@ mp_to_unsigned_bin (mp_int * a, unsigned char *b) mp_clear (&t); return MP_OKAY; } +#endif /* End: bn_mp_to_unsigned_bin.c */ /* Start: bn_mp_toom_mul.c */ +#include +#ifdef BN_MP_TOOM_MUL_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -7013,9 +7213,13 @@ mp_to_unsigned_bin (mp_int * a, unsigned char *b) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include -/* multiplication using the Toom-Cook 3-way algorithm */ +/* multiplication using the Toom-Cook 3-way algorithm + * + * Much more complicated than Karatsuba but has a lower asymptotic running time of + * O(N**1.464). This algorithm is only particularly useful on VERY large + * inputs (we're talking 1000s of digits here...). +*/ int mp_toom_mul(mp_int *a, mp_int *b, mp_int *c) { mp_int w0, w1, w2, w3, w4, tmp1, tmp2, a0, a1, a2, b0, b1, b2; @@ -7271,10 +7475,13 @@ ERR: return res; } +#endif /* End: bn_mp_toom_mul.c */ /* Start: bn_mp_toom_sqr.c */ +#include +#ifdef BN_MP_TOOM_SQR_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -7289,7 +7496,6 @@ ERR: * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* squaring using Toom-Cook 3-way algorithm */ int @@ -7495,10 +7701,13 @@ ERR: return res; } +#endif /* End: bn_mp_toom_sqr.c */ /* Start: bn_mp_toradix.c */ +#include +#ifdef BN_MP_TORADIX_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -7513,7 +7722,6 @@ ERR: * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* stores a bignum as a ASCII string in a given radix (2..64) */ int mp_toradix (mp_int * a, char *str, int radix) @@ -7568,10 +7776,13 @@ int mp_toradix (mp_int * a, char *str, int radix) return MP_OKAY; } +#endif /* End: bn_mp_toradix.c */ /* Start: bn_mp_toradix_n.c */ +#include +#ifdef BN_MP_TORADIX_N_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -7586,7 +7797,6 @@ int mp_toradix (mp_int * a, char *str, int radix) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* stores a bignum as a ASCII string in a given radix (2..64) * @@ -7655,10 +7865,13 @@ int mp_toradix_n(mp_int * a, char *str, int radix, int maxlen) return MP_OKAY; } +#endif /* End: bn_mp_toradix_n.c */ /* Start: bn_mp_unsigned_bin_size.c */ +#include +#ifdef BN_MP_UNSIGNED_BIN_SIZE_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -7673,7 +7886,6 @@ int mp_toradix_n(mp_int * a, char *str, int radix, int maxlen) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* get the size for an unsigned equivalent */ int @@ -7682,10 +7894,13 @@ mp_unsigned_bin_size (mp_int * a) int size = mp_count_bits (a); return (size / 8 + ((size & 7) != 0 ? 1 : 0)); } +#endif /* End: bn_mp_unsigned_bin_size.c */ /* Start: bn_mp_xor.c */ +#include +#ifdef BN_MP_XOR_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -7700,7 +7915,6 @@ mp_unsigned_bin_size (mp_int * a) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* XOR two ints together */ int @@ -7724,17 +7938,20 @@ mp_xor (mp_int * a, mp_int * b, mp_int * c) } for (ix = 0; ix < px; ix++) { - t.dp[ix] ^= x->dp[ix]; + } mp_clamp (&t); mp_exch (c, &t); mp_clear (&t); return MP_OKAY; } +#endif /* End: bn_mp_xor.c */ /* Start: bn_mp_zero.c */ +#include +#ifdef BN_MP_ZERO_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -7749,7 +7966,6 @@ mp_xor (mp_int * a, mp_int * b, mp_int * c) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* set to zero */ void @@ -7759,65 +7975,13 @@ mp_zero (mp_int * a) a->used = 0; memset (a->dp, 0, sizeof (mp_digit) * a->alloc); } +#endif /* End: bn_mp_zero.c */ -/* Start: bn_prime_sizes_tab.c */ -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * 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 - -/* this table gives the # of rabin miller trials for a prob of failure lower than 2^-96 */ -static const struct { - int k, t; -} sizes[] = { -{ 128, 28 }, -{ 256, 16 }, -{ 384, 10 }, -{ 512, 7 }, -{ 640, 6 }, -{ 768, 5 }, -{ 896, 4 }, -{ 1024, 4 }, -{ 1152, 3 }, -{ 1280, 3 }, -{ 1408, 3 }, -{ 1536, 3 }, -{ 1664, 3 }, -{ 1792, 2 } }; - -/* returns # of RM trials required for a given bit size */ -int mp_prime_rabin_miller_trials(int size) -{ - int x; - - for (x = 0; x < (int)(sizeof(sizes)/(sizeof(sizes[0]))); x++) { - if (sizes[x].k == size) { - return sizes[x].t; - } else if (sizes[x].k > size) { - return (x == 0) ? sizes[0].t : sizes[x - 1].t; - } - } - return 1; -} - - - -/* End: bn_prime_sizes_tab.c */ - /* Start: bn_prime_tab.c */ +#include +#ifdef BN_PRIME_TAB_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -7832,7 +7996,6 @@ int mp_prime_rabin_miller_trials(int size) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include const mp_digit __prime_tab[] = { 0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013, 0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035, @@ -7873,10 +8036,13 @@ const mp_digit __prime_tab[] = { 0x062B, 0x062F, 0x063D, 0x0641, 0x0647, 0x0649, 0x064D, 0x0653 #endif }; +#endif /* End: bn_prime_tab.c */ /* Start: bn_reverse.c */ +#include +#ifdef BN_REVERSE_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -7891,7 +8057,6 @@ const mp_digit __prime_tab[] = { * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* reverse an array, used for radix code */ void @@ -7910,10 +8075,13 @@ bn_reverse (unsigned char *s, int len) --iy; } } +#endif /* End: bn_reverse.c */ /* Start: bn_s_mp_add.c */ +#include +#ifdef BN_S_MP_ADD_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -7928,7 +8096,6 @@ bn_reverse (unsigned char *s, int len) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* low level addition, based on HAC pp.594, Algorithm 14.7 */ int @@ -8017,10 +8184,13 @@ s_mp_add (mp_int * a, mp_int * b, mp_int * c) mp_clamp (c); return MP_OKAY; } +#endif /* End: bn_s_mp_add.c */ /* Start: bn_s_mp_exptmod.c */ +#include +#ifdef BN_S_MP_EXPTMOD_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -8035,7 +8205,6 @@ s_mp_add (mp_int * a, mp_int * b, mp_int * c) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include #ifdef MP_LOW_MEM #define TAB_SIZE 32 @@ -8255,10 +8424,13 @@ __M: } return err; } +#endif /* End: bn_s_mp_exptmod.c */ /* Start: bn_s_mp_mul_digs.c */ +#include +#ifdef BN_S_MP_MUL_DIGS_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -8273,7 +8445,6 @@ __M: * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* multiplies |a| * |b| and only computes upto digs digits of result * HAC pp. 595, Algorithm 14.12 Modified so you can control how @@ -8344,10 +8515,13 @@ s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) mp_clear (&t); return MP_OKAY; } +#endif /* End: bn_s_mp_mul_digs.c */ /* Start: bn_s_mp_mul_high_digs.c */ +#include +#ifdef BN_S_MP_MUL_HIGH_DIGS_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -8362,7 +8536,6 @@ s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* multiplies |a| * |b| and does not compute the lower digs digits * [meant to get the higher part of the product] @@ -8377,10 +8550,12 @@ s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs) mp_digit tmpx, *tmpt, *tmpy; /* can we use the fast multiplier? */ +#ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_C if (((a->used + b->used + 1) < MP_WARRAY) && MIN (a->used, b->used) < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { return fast_s_mp_mul_high_digs (a, b, c, digs); } +#endif if ((res = mp_init_size (&t, a->used + b->used + 1)) != MP_OKAY) { return res; @@ -8421,10 +8596,13 @@ s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs) mp_clear (&t); return MP_OKAY; } +#endif /* End: bn_s_mp_mul_high_digs.c */ /* Start: bn_s_mp_sqr.c */ +#include +#ifdef BN_S_MP_SQR_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -8439,7 +8617,6 @@ s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* low level squaring, b = a*a, HAC pp.596-597, Algorithm 14.16 */ int @@ -8504,10 +8681,13 @@ s_mp_sqr (mp_int * a, mp_int * b) mp_clear (&t); return MP_OKAY; } +#endif /* End: bn_s_mp_sqr.c */ /* Start: bn_s_mp_sub.c */ +#include +#ifdef BN_S_MP_SUB_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -8522,7 +8702,6 @@ s_mp_sqr (mp_int * a, mp_int * b) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* low level subtraction (assumes |a| > |b|), HAC pp.595 Algorithm 14.9 */ int @@ -8591,10 +8770,13 @@ s_mp_sub (mp_int * a, mp_int * b, mp_int * c) return MP_OKAY; } +#endif /* End: bn_s_mp_sub.c */ /* Start: bncore.c */ +#include +#ifdef BNCORE_C /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision @@ -8609,26 +8791,21 @@ s_mp_sub (mp_int * a, mp_int * b, mp_int * c) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include /* Known optimal configurations CPU /Compiler /MUL CUTOFF/SQR CUTOFF ------------------------------------------------------------- - Intel P4 Northwood /GCC v3.3.3 / 121/ 128/SSE patches ;-) - Intel P4 Northwood /GCC v3.3.3 / 59/ 81/profiled build - Intel P4 Northwood /GCC v3.3.3 / 59/ 80/profiled_single build - Intel P4 Northwood /ICC v8.0 / 57/ 70/profiled build - Intel P4 Northwood /ICC v8.0 / 54/ 76/profiled_single build - AMD Athlon XP /GCC v3.2 / 109/ 127/ + Intel P4 Northwood /GCC v3.4.1 / 88/ 128/LTM 0.32 ;-) */ -int KARATSUBA_MUL_CUTOFF = 121, /* Min. number of digits before Karatsuba multiplication is used. */ - KARATSUBA_SQR_CUTOFF = 128, /* Min. number of digits before Karatsuba squaring is used. */ +int KARATSUBA_MUL_CUTOFF = 88, /* Min. number of digits before Karatsuba multiplication is used. */ + KARATSUBA_SQR_CUTOFF = 128, /* Min. number of digits before Karatsuba squaring is used. */ TOOM_MUL_CUTOFF = 350, /* no optimal values of these are known yet so set em high */ TOOM_SQR_CUTOFF = 400; +#endif /* End: bncore.c */ diff --git a/mycrypt.h b/mycrypt.h index 43a93e9..1d6a938 100644 --- a/mycrypt.h +++ b/mycrypt.h @@ -16,8 +16,8 @@ extern "C" { #endif /* version */ -#define CRYPT 0x0098 -#define SCRYPT "0.98" +#define CRYPT 0x0099 +#define SCRYPT "0.99" /* max size of either a cipher/hash block or symmetric key [largest of the two] */ #define MAXBLOCKSIZE 64 diff --git a/mycrypt_argchk.h b/mycrypt_argchk.h index 090d4d0..69f27d6 100644 --- a/mycrypt_argchk.h +++ b/mycrypt_argchk.h @@ -5,7 +5,7 @@ #include /* this is the default LibTomCrypt macro */ - void crypt_argchk(char *v, char *s, int d); +void crypt_argchk(char *v, char *s, int d); #define _ARGCHK(x) if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } #elif ARGTYPE == 1 diff --git a/mycrypt_cfg.h b/mycrypt_cfg.h index 4d40c70..b440e0b 100644 --- a/mycrypt_cfg.h +++ b/mycrypt_cfg.h @@ -42,6 +42,12 @@ int XMEMCMP(const void *s1, const void *s2, size_t n); #define ENDIAN_64BITWORD #endif +/* detect amd64 */ +#if defined(__x86_64__) + #define ENDIAN_LITTLE + #define ENDIAN_64BITWORD +#endif + /* #define ENDIAN_LITTLE */ /* #define ENDIAN_BIG */ diff --git a/mycrypt_custom.h b/mycrypt_custom.h index c71579f..03058bb 100644 --- a/mycrypt_custom.h +++ b/mycrypt_custom.h @@ -18,7 +18,7 @@ #define XCLOCKS_PER_SEC CLOCKS_PER_SEC /* Use small code where possible */ -#define SMALL_CODE +// #define SMALL_CODE /* Enable self-test test vector checking */ #define LTC_TEST @@ -27,7 +27,7 @@ // #define CLEAN_STACK /* disable all file related functions */ -//#define NO_FILE +// #define NO_FILE /* various ciphers */ #define BLOWFISH @@ -37,10 +37,13 @@ #define SAFERP #define RIJNDAEL #define XTEA +/* _TABLES tells it to use tables during setup, _SMALL means to use the smaller scheduled key format + * (saves 4KB of ram), _ALL_TABLES enables all tables during setup */ #define TWOFISH #define TWOFISH_TABLES // #define TWOFISH_ALL_TABLES // #define TWOFISH_SMALL +/* DES includes EDE triple-DES */ #define DES #define CAST5 #define NOEKEON @@ -50,7 +53,7 @@ */ //#define SAFER -/* modes of operation */ +/* block cipher modes of operation */ #define CFB #define OFB #define ECB @@ -58,6 +61,7 @@ #define CTR /* hash functions */ +#define CHC_HASH #define WHIRLPOOL #define SHA512 #define SHA384 @@ -147,16 +151,7 @@ /* Include the MPI functionality? (required by the PK algorithms) */ #define MPI -/* Use SSE2 optimizations in LTM? Requires GCC or ICC and a P4 or K8 processor */ -// #define LTMSSE - -/* prevents the code from being "unportable" at least to non i386 platforms */ -#if defined(LTMSSE) && !( (defined(__GNUC__) && defined(__i386__)) || defined(INTEL_CC)) - #warning LTMSSE is only available for GNU CC (i386) or Intel CC - #undef LTMSSE -#endif - -/* PKCS #1 and #5 stuff */ +/* PKCS #1 (RSA) and #5 (Password Handling) stuff */ #define PKCS_1 #define PKCS_5 diff --git a/mycrypt_hash.h b/mycrypt_hash.h index b661d12..d5d8900 100644 --- a/mycrypt_hash.h +++ b/mycrypt_hash.h @@ -78,7 +78,18 @@ struct whirlpool_state { }; #endif +#ifdef CHC_HASH +struct chc_state { + ulong64 length; + unsigned char state[MAXBLOCKSIZE], buf[MAXBLOCKSIZE]; + ulong32 curlen; +}; +#endif + typedef union Hash_state { +#ifdef CHC_HASH + struct chc_state chc; +#endif #ifdef WHIRLPOOL struct whirlpool_state whirlpool; #endif @@ -118,26 +129,34 @@ extern struct _hash_descriptor { unsigned long blocksize; /* the block size the hash uses */ unsigned char DER[64]; /* DER encoded identifier */ unsigned long DERlen; /* length of DER encoding */ - void (*init)(hash_state *); + int (*init)(hash_state *); int (*process)(hash_state *, const unsigned char *, unsigned long); int (*done)(hash_state *, unsigned char *); - int (*test)(void); + int (*test)(void); } hash_descriptor[]; +#ifdef CHC_HASH + int chc_register(int cipher); + int chc_init(hash_state * md); + int chc_process(hash_state * md, const unsigned char *buf, unsigned long len); + int chc_done(hash_state * md, unsigned char *hash); + int chc_test(void); + extern const struct _hash_descriptor chc_desc; +#endif #ifdef WHIRLPOOL - void whirlpool_init(hash_state * md); + int whirlpool_init(hash_state * md); int whirlpool_process(hash_state * md, const unsigned char *buf, unsigned long len); int whirlpool_done(hash_state * md, unsigned char *hash); - int whirlpool_test(void); + int whirlpool_test(void); extern const struct _hash_descriptor whirlpool_desc; #endif #ifdef SHA512 - void sha512_init(hash_state * md); + int sha512_init(hash_state * md); int sha512_process(hash_state * md, const unsigned char *buf, unsigned long len); int sha512_done(hash_state * md, unsigned char *hash); - int sha512_test(void); + int sha512_test(void); extern const struct _hash_descriptor sha512_desc; #endif @@ -145,89 +164,88 @@ extern struct _hash_descriptor { #ifndef SHA512 #error SHA512 is required for SHA384 #endif - void sha384_init(hash_state * md); + int sha384_init(hash_state * md); #define sha384_process sha512_process int sha384_done(hash_state * md, unsigned char *hash); - int sha384_test(void); + int sha384_test(void); extern const struct _hash_descriptor sha384_desc; #endif #ifdef SHA256 - void sha256_init(hash_state * md); + int sha256_init(hash_state * md); int sha256_process(hash_state * md, const unsigned char *buf, unsigned long len); int sha256_done(hash_state * md, unsigned char *hash); - int sha256_test(void); + int sha256_test(void); extern const struct _hash_descriptor sha256_desc; #ifdef SHA224 #ifndef SHA256 #error SHA256 is required for SHA224 #endif - void sha224_init(hash_state * md); + int sha224_init(hash_state * md); #define sha224_process sha256_process int sha224_done(hash_state * md, unsigned char *hash); - int sha224_test(void); + int sha224_test(void); extern const struct _hash_descriptor sha224_desc; #endif #endif #ifdef SHA1 - void sha1_init(hash_state * md); + int sha1_init(hash_state * md); int sha1_process(hash_state * md, const unsigned char *buf, unsigned long len); int sha1_done(hash_state * md, unsigned char *hash); - int sha1_test(void); + int sha1_test(void); extern const struct _hash_descriptor sha1_desc; #endif #ifdef MD5 - void md5_init(hash_state * md); + int md5_init(hash_state * md); int md5_process(hash_state * md, const unsigned char *buf, unsigned long len); int md5_done(hash_state * md, unsigned char *hash); - int md5_test(void); + int md5_test(void); extern const struct _hash_descriptor md5_desc; #endif #ifdef MD4 - void md4_init(hash_state * md); + int md4_init(hash_state * md); int md4_process(hash_state * md, const unsigned char *buf, unsigned long len); int md4_done(hash_state * md, unsigned char *hash); - int md4_test(void); + int md4_test(void); extern const struct _hash_descriptor md4_desc; #endif #ifdef MD2 - void md2_init(hash_state * md); + int md2_init(hash_state * md); int md2_process(hash_state * md, const unsigned char *buf, unsigned long len); int md2_done(hash_state * md, unsigned char *hash); - int md2_test(void); + int md2_test(void); extern const struct _hash_descriptor md2_desc; #endif #ifdef TIGER - void tiger_init(hash_state * md); + int tiger_init(hash_state * md); int tiger_process(hash_state * md, const unsigned char *buf, unsigned long len); int tiger_done(hash_state * md, unsigned char *hash); - int tiger_test(void); + int tiger_test(void); extern const struct _hash_descriptor tiger_desc; #endif #ifdef RIPEMD128 - void rmd128_init(hash_state * md); + int rmd128_init(hash_state * md); int rmd128_process(hash_state * md, const unsigned char *buf, unsigned long len); int rmd128_done(hash_state * md, unsigned char *hash); - int rmd128_test(void); + int rmd128_test(void); extern const struct _hash_descriptor rmd128_desc; #endif #ifdef RIPEMD160 - void rmd160_init(hash_state * md); + int rmd160_init(hash_state * md); int rmd160_process(hash_state * md, const unsigned char *buf, unsigned long len); int rmd160_done(hash_state * md, unsigned char *hash); - int rmd160_test(void); + int rmd160_test(void); extern const struct _hash_descriptor rmd160_desc; #endif - int find_hash(const char *name); int find_hash_id(unsigned char ID); int find_hash_any(const char *name, int digestlen); @@ -244,6 +262,7 @@ extern struct _hash_descriptor { int func_name (hash_state * md, const unsigned char *buf, unsigned long len) \ { \ unsigned long n; \ + int err; \ _ARGCHK(md != NULL); \ _ARGCHK(buf != NULL); \ if (md-> state_var .curlen > sizeof(md-> state_var .buf)) { \ @@ -251,7 +270,9 @@ int func_name (hash_state * md, const unsigned char *buf, unsigned long len) } \ while (len > 0) { \ if (md-> state_var .curlen == 0 && len >= block_size) { \ - compress_name (md, (unsigned char *)buf); \ + if ((err = compress_name (md, (unsigned char *)buf)) != CRYPT_OK) { \ + return err; \ + } \ md-> state_var .length += block_size * 8; \ buf += block_size; \ len -= block_size; \ @@ -262,7 +283,9 @@ int func_name (hash_state * md, const unsigned char *buf, unsigned long len) buf += n; \ len -= n; \ if (md-> state_var .curlen == block_size) { \ - compress_name (md, md-> state_var .buf); \ + if ((err = compress_name (md, md-> state_var .buf)) != CRYPT_OK) {\ + return err; \ + } \ md-> state_var .length += 8*block_size; \ md-> state_var .curlen = 0; \ } \ diff --git a/mycrypt_macros.h b/mycrypt_macros.h index cd69cd3..6e2eaa2 100644 --- a/mycrypt_macros.h +++ b/mycrypt_macros.h @@ -10,7 +10,11 @@ /* this is the "32-bit at least" data type * Re-define it to suit your platform but it must be at least 32-bits */ -typedef unsigned long ulong32; +#if defined(__x86_64__) + typedef unsigned ulong32; +#else + typedef unsigned long ulong32; +#endif /* ---- HELPER MACROS ---- */ #ifdef ENDIAN_NEUTRAL @@ -194,9 +198,9 @@ typedef unsigned long ulong32; #define ROR(x,n) _lrotr(x,n) #define ROL(x,n) _lrotl(x,n) -#elif defined(__GNUC__) && defined(__i386__) && !defined(INTEL_CC) +#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) && !defined(INTEL_CC) -static inline unsigned long ROL(unsigned long word, int i) +static inline unsigned ROL(unsigned word, int i) { __asm__("roll %%cl,%0" :"=r" (word) @@ -204,7 +208,7 @@ static inline unsigned long ROL(unsigned long word, int i) return word; } -static inline unsigned long ROR(unsigned long word, int i) +static inline unsigned ROR(unsigned word, int i) { __asm__("rorl %%cl,%0" :"=r" (word) @@ -220,6 +224,26 @@ static inline unsigned long ROR(unsigned long word, int i) #endif +#if defined(__GNUCC__) && defined(__x86_64__) + +static inline unsigned long ROL64(unsigned long word, int i) +{ + __asm__("rolq %%cl,%0" + :"=r" (word) + :"0" (word),"c" (i)); + return word; +} + +static inline unsigned long ROR64(unsigned long word, int i) +{ + __asm__("rorq %%cl,%0" + :"=r" (word) + :"0" (word),"c" (i)); + return word; +} + +#else + #define ROL64(x, y) \ ( (((x)<<((ulong64)(y)&63)) | \ (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)64-((y)&63)))) & CONST64(0xFFFFFFFFFFFFFFFF)) @@ -228,6 +252,8 @@ static inline unsigned long ROR(unsigned long word, int i) ( ((((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)(y)&CONST64(63))) | \ ((x)<<((ulong64)(64-((y)&CONST64(63)))))) & CONST64(0xFFFFFFFFFFFFFFFF)) +#endif + #undef MAX #undef MIN #define MAX(x, y) ( ((x)>(y))?(x):(y) ) diff --git a/mycrypt_pk.h b/mycrypt_pk.h index 9afacda..6345116 100644 --- a/mycrypt_pk.h +++ b/mycrypt_pk.h @@ -67,7 +67,6 @@ #define PK_PRIVATE 0 /* PK private keys */ #define PK_PUBLIC 1 /* PK public keys */ -#define PK_PRIVATE_OPTIMIZED 2 /* PK private key [rsa optimized] */ /* ---- PACKET ---- */ #ifdef PACKET @@ -90,7 +89,7 @@ typedef struct Rsa_key { int type; - mp_int e, d, N, qP, pQ, dP, dQ, p, q; + mp_int e, d, N, p, q, qP, dP, dQ; } rsa_key; int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key); @@ -276,3 +275,11 @@ typedef struct { int dsa_verify_key(dsa_key *key, int *stat); #endif + +/* DER handling */ +int der_encode_integer(mp_int *num, unsigned char *out, unsigned long *outlen); +int der_decode_integer(const unsigned char *in, unsigned long *inlen, mp_int *num); +int der_length_integer(mp_int *num, unsigned long *len); +int der_put_multi_integer(unsigned char *dst, unsigned long *outlen, mp_int *num, ...); +int der_get_multi_integer(const unsigned char *src, unsigned long *inlen, mp_int *num, ...); + diff --git a/mycrypt_prng.h b/mycrypt_prng.h index 76d342e..e706849 100644 --- a/mycrypt_prng.h +++ b/mycrypt_prng.h @@ -60,8 +60,8 @@ extern struct _prng_descriptor { int (*ready)(prng_state *); unsigned long (*read)(unsigned char *, unsigned long, prng_state *); int (*done)(prng_state *); - int (*export)(unsigned char *, unsigned long *, prng_state *); - int (*import)(const unsigned char *, unsigned long, prng_state *); + int (*pexport)(unsigned char *, unsigned long *, prng_state *); + int (*pimport)(const unsigned char *, unsigned long, prng_state *); int (*test)(void); } prng_descriptor[]; diff --git a/notes/hash_tv.txt b/notes/hash_tv.txt index 7fd9062..4f2714d 100644 --- a/notes/hash_tv.txt +++ b/notes/hash_tv.txt @@ -1734,3 +1734,38 @@ Hash: whirlpool 127: 3C9A7F387B7104DF19CF264B0B5821B2E46E44ADC79262546E98FFA113EB3D45799EAC78CCA4643C937FCC3C1D249A212FACB34C63D45EEC81069095D7CDCE7B 128: 803A3B37C89E84FBBEC75BEE3D00DD728FFC4246B5A5E989DC8DC2CD0F7937966AB78C79E1D4648EE6EB40F3D70491CB46B8AB42E155672E2AB8374FCF70DD79 +Hash: chc_hash + 0: 4047929F1F572643B55F829EB3291D11 + 1: 8898FD04F810507740E7A8DBF44C18E8 + 2: 1445928BB912A6D3C5111923B6C5D48D + 3: D85B2E8854D16A440CF32DDDA741DA52 + 4: 5F3082124472598098B03649EA409CDC + 5: 604A19622A06D0486D559A07C95B297A + 6: A16F89E4DACA6C8174C9D66AA23B15AF + 7: FC6893F79A2D28315FBBEFCAF0280793 + 8: 6A80F04CB93B1CFB947DED28141E877A + 9: D036D0B4DEF1FA138C3181367143D1A9 + 10: F031A2DC2A196B268046F73728EE7831 + 11: 2E05C9B5A43CFB01AD026ABA8AE8201F + 12: 8B49EF0BC936792F905E61AE621E63C3 + 13: 485CF5E83BC66843D446D9922547E43B + 14: 704767A75D1FD6639CE72291AE1F6CD8 + 15: 19F6228C2531747CB20F644F9EC65691 + 16: B78FEC0628D7F47B042A3C15C57750FB + 17: 3EF9AFAAFAE9C80D09CD078E1CC0BD8A + 18: 5E4501C8DD0D49589F4FFA20F278D316 + 19: 00D2D0FDD0E0476C9D40DE5A04508849 + 20: CC7382E78D8DF07F0BAB66203F191745 + 21: 85B841BCCCB4AD2420BCABCFD06A0757 + 22: 7159E38F4D7E4CEBEBF86A65A984BA2A + 23: C8949A9D92601726F77E1AEF0E5F1E0F + 24: 8CE35EF6EC7DDA294134077420159F68 + 25: A0F4E4522832676B49E7CD393E6D9761 + 26: F55C27D180948585819833322D7BC4CA + 27: 0A3975A0113E1FE6A66F8C7D529715B5 + 28: F77135C5D04096181305C0906BAEE789 + 29: 31FF81B49B9003D73F878F810D49C851 + 30: BE1E12BF021D0DB2FC5CE7D5348A1DE7 + 31: CB4AF60D7340EC6849574DF1E5BAA24E + 32: 7C5ABDBA19396D7BE48C2A84F8CC747B + diff --git a/notes/hmac_tv.txt b/notes/hmac_tv.txt index 3003490..18edd70 100644 --- a/notes/hmac_tv.txt +++ b/notes/hmac_tv.txt @@ -1734,3 +1734,38 @@ HMAC-whirlpool 127: 1D8B2525E519A3FF8BDAAF31E80EE695F5914B78E7DAB801729B5D84C3A7A2B36A33803F5E0723981CF8A9586EC1BEABC58154EFD919AFF08935FBD756327AAB 128: 4AABF1C3F24C20FFAA61D6106E32EF1BB7CDEB607354BD4B6251893941730054244E198EECD4943C77082CC9B406A2E12271BCA455DF15D3613336615C36B22E +HMAC-chc_hash + 0: 0607F24D43AA98A86FCC45B53DA04F9D + 1: BE4FB5E0BC4BD8132DB14BCBD7E4CD10 + 2: A3246C609FE39D7C9F7CFCF16185FB48 + 3: 3C7EA951205937240F0756BC0F2F4D1B + 4: 7F69A5DD411DFE6BB99D1B8391B31272 + 5: DCB4D4D7F3B9AF6F51F30DCF733068CC + 6: 1363B27E6B28BCD8AE3DCD0F55B387D7 + 7: BB525342845B1253CFE98F00237A85F3 + 8: 89FB247A36A9926FDA10F2013119151B + 9: 54EB023EF9CE37EDC986373E23A9ED16 + 10: 2358D8884471CB1D9E233107C7A7A4A0 + 11: 94BAB092B00574C5FBEB1D7E54B684C4 + 12: DF1819707621B8A66D9709397E92DC2F + 13: 3044DFFC7947787FDB12F62141B9E4FB + 14: 9EA9943FC2635AD852D1C5699234915D + 15: 1CC75C985BE6EDD3AD5907ED72ECE05E + 16: 1A826C4817FF59E686A59B0B96C9A619 + 17: 44DB2A64264B125DE535A182CB7B2B2C + 18: 4741D46F73F2A860F95751E7E14CC244 + 19: 13FDD4463084FEEB24F713DD9858E7F4 + 20: D3308382E65E588D576D970A792BAC61 + 21: 38E04BD5885FEA9E140F065F37DD09FC + 22: 5C309499657F24C1812FD8B926A419E2 + 23: D1FDB9E8AC245737DA836D68FA507736 + 24: F6924085988770FCC3BC9EEA8F72604E + 25: C72B261A79411F74D707C6B6F45823BD + 26: 2ED2333EBAC77F291FC6E844F2A7E42D + 27: CE0D3EF674917CEA5171F1A52EA62AAE + 28: 55EDEAC9F935ABEAF2956C8E83F3E447 + 29: 820B799CB66DC9763FFD9AB634D971EC + 30: E14B18AB25025BF5DF2C1A73C235AD8B + 31: DE9F394575B9F525A734F302F0DB0A42 + 32: 625ED3B09144ADFF57B6659BB2044FBE + diff --git a/omac_done.c b/omac_done.c index f065a1d..958ee3e 100644 --- a/omac_done.c +++ b/omac_done.c @@ -15,10 +15,12 @@ int omac_done(omac_state *state, unsigned char *out, unsigned long *outlen) { - int err, mode, x; + int err, mode; + unsigned x; - _ARGCHK(state != NULL); - _ARGCHK(out != NULL); + _ARGCHK(state != NULL); + _ARGCHK(out != NULL); + _ARGCHK(outlen != NULL); if ((err = cipher_is_valid(state->cipher_idx)) != CRYPT_OK) { return err; } @@ -43,7 +45,7 @@ int omac_done(omac_state *state, unsigned char *out, unsigned long *outlen) } /* now xor prev + Lu[mode] */ - for (x = 0; x < state->blklen; x++) { + for (x = 0; x < (unsigned)state->blklen; x++) { state->block[x] ^= state->prev[x] ^ state->Lu[mode][x]; } @@ -51,7 +53,7 @@ int omac_done(omac_state *state, unsigned char *out, unsigned long *outlen) cipher_descriptor[state->cipher_idx].ecb_encrypt(state->block, state->block, &state->key); /* output it */ - for (x = 0; x < state->blklen && (unsigned long)x < *outlen; x++) { + for (x = 0; x < (unsigned)state->blklen && x < *outlen; x++) { out[x] = state->block[x]; } *outlen = x; diff --git a/omac_test.c b/omac_test.c index 2d50d9a..e346073 100644 --- a/omac_test.c +++ b/omac_test.c @@ -65,7 +65,7 @@ int omac_test(void) }; unsigned char out[16]; - int x, y, err, idx; + int x, err, idx; unsigned long len; @@ -83,8 +83,11 @@ int omac_test(void) } if (memcmp(out, tests[x].tag, 16) != 0) { +#if 0 + int y; printf("\n\nTag: "); for (y = 0; y < 16; y++) printf("%02x", out[y]); printf("\n\n"); +#endif return CRYPT_FAIL_TESTVECTOR; } } diff --git a/pkcs_1_mgf1.c b/pkcs_1_mgf1.c index 3add990..8b2bf8b 100644 --- a/pkcs_1_mgf1.c +++ b/pkcs_1_mgf1.c @@ -56,7 +56,9 @@ int pkcs_1_mgf1(const unsigned char *seed, unsigned long seedlen, ++counter; /* get hash of seed || counter */ - hash_descriptor[hash_idx].init(md); + if ((err = hash_descriptor[hash_idx].init(md)) != CRYPT_OK) { + goto __ERR; + } if ((err = hash_descriptor[hash_idx].process(md, seed, seedlen)) != CRYPT_OK) { goto __ERR; } diff --git a/pkcs_1_pss_decode.c b/pkcs_1_pss_decode.c index ff01b76..564c90c 100644 --- a/pkcs_1_pss_decode.c +++ b/pkcs_1_pss_decode.c @@ -118,7 +118,9 @@ int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen, } /* M = (eight) 0x00 || msghash || salt, mask = H(M) */ - hash_descriptor[hash_idx].init(&md); + if ((err = hash_descriptor[hash_idx].init(&md)) != CRYPT_OK) { + goto __ERR; + } zeromem(mask, 8); if ((err = hash_descriptor[hash_idx].process(&md, mask, 8)) != CRYPT_OK) { goto __ERR; diff --git a/pkcs_1_pss_encode.c b/pkcs_1_pss_encode.c index 4ee1d51..43691fc 100644 --- a/pkcs_1_pss_encode.c +++ b/pkcs_1_pss_encode.c @@ -77,7 +77,9 @@ int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen, } /* M = (eight) 0x00 || msghash || salt, hash = H(M) */ - hash_descriptor[hash_idx].init(&md); + if ((err = hash_descriptor[hash_idx].init(&md)) != CRYPT_OK) { + goto __ERR; + } zeromem(DB, 8); if ((err = hash_descriptor[hash_idx].process(&md, DB, 8)) != CRYPT_OK) { goto __ERR; diff --git a/pkcs_5_1.c b/pkcs_5_1.c index b87f195..a98affa 100644 --- a/pkcs_5_1.c +++ b/pkcs_5_1.c @@ -47,7 +47,9 @@ int pkcs_5_alg1(const unsigned char *password, unsigned long password_len, } /* hash initial password + salt */ - hash_descriptor[hash_idx].init(md); + if ((err = hash_descriptor[hash_idx].init(md)) != CRYPT_OK) { + goto __ERR; + } if ((err = hash_descriptor[hash_idx].process(md, password, password_len)) != CRYPT_OK) { goto __ERR; } diff --git a/rmd128.c b/rmd128.c index 13a3135..f9351de 100644 --- a/rmd128.c +++ b/rmd128.c @@ -75,9 +75,9 @@ const struct _hash_descriptor rmd128_desc = (a) = ROL((a), (s)); #ifdef CLEAN_STACK -static void _rmd128_compress(hash_state *md, unsigned char *buf) +static int _rmd128_compress(hash_state *md, unsigned char *buf) #else -static void rmd128_compress(hash_state *md, unsigned char *buf) +static int rmd128_compress(hash_state *md, unsigned char *buf) #endif { ulong32 aa,bb,cc,dd,aaa,bbb,ccc,ddd,X[16]; @@ -244,17 +244,21 @@ static void rmd128_compress(hash_state *md, unsigned char *buf) 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; + + return CRYPT_OK; } #ifdef CLEAN_STACK -static void rmd128_compress(hash_state *md, unsigned char *buf) +static int rmd128_compress(hash_state *md, unsigned char *buf) { - _rmd128_compress(md, buf); + int err; + err = _rmd128_compress(md, buf); burn_stack(sizeof(ulong32) * 24 + sizeof(int)); + return err; } #endif -void rmd128_init(hash_state * md) +int rmd128_init(hash_state * md) { _ARGCHK(md != NULL); md->rmd128.state[0] = 0x67452301UL; @@ -263,6 +267,7 @@ void rmd128_init(hash_state * md) md->rmd128.state[3] = 0x10325476UL; md->rmd128.curlen = 0; md->rmd128.length = 0; + return CRYPT_OK; } HASH_PROCESS(rmd128_process, rmd128_compress, rmd128, 64) diff --git a/rmd160.c b/rmd160.c index 6b49076..2079448 100644 --- a/rmd160.c +++ b/rmd160.c @@ -96,9 +96,9 @@ const struct _hash_descriptor rmd160_desc = #ifdef CLEAN_STACK -static void _rmd160_compress(hash_state *md, unsigned char *buf) +static int _rmd160_compress(hash_state *md, unsigned char *buf) #else -static void rmd160_compress(hash_state *md, unsigned char *buf) +static int rmd160_compress(hash_state *md, unsigned char *buf) #endif { ulong32 aa,bb,cc,dd,ee,aaa,bbb,ccc,ddd,eee,X[16]; @@ -303,17 +303,21 @@ static void rmd160_compress(hash_state *md, unsigned char *buf) 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; + + return CRYPT_OK; } #ifdef CLEAN_STACK -static void rmd160_compress(hash_state *md, unsigned char *buf) +static int rmd160_compress(hash_state *md, unsigned char *buf) { - _rmd160_compress(md, buf); + int err; + err = _rmd160_compress(md, buf); burn_stack(sizeof(ulong32) * 26 + sizeof(int)); + return err; } #endif -void rmd160_init(hash_state * md) +int rmd160_init(hash_state * md) { _ARGCHK(md != NULL); md->rmd160.state[0] = 0x67452301UL; @@ -323,6 +327,7 @@ void rmd160_init(hash_state * md) md->rmd160.state[4] = 0xc3d2e1f0UL; md->rmd160.curlen = 0; md->rmd160.length = 0; + return CRYPT_OK; } HASH_PROCESS(rmd160_process, rmd160_compress, rmd160, 64) diff --git a/rsa_export.c b/rsa_export.c index a5c20c0..bee5cf6 100644 --- a/rsa_export.c +++ b/rsa_export.c @@ -13,60 +13,43 @@ #ifdef MRSA -/* Export an RSA key */ +/* This will export either an RSAPublicKey or RSAPrivateKey [defined in PKCS #1 v2.1] */ int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key) { - unsigned long y, z; int err; _ARGCHK(out != NULL); _ARGCHK(outlen != NULL); _ARGCHK(key != NULL); - - /* can we store the static header? */ - if (*outlen < (PACKET_SIZE + 1)) { - return CRYPT_BUFFER_OVERFLOW; - } /* type valid? */ - if (!(key->type == PK_PRIVATE || key->type == PK_PRIVATE_OPTIMIZED) && - (type == PK_PRIVATE || type == PK_PRIVATE_OPTIMIZED)) { + if (!(key->type == PK_PRIVATE) && (type == PK_PRIVATE)) { return CRYPT_PK_INVALID_TYPE; } + + if (type == PK_PRIVATE) { + /* private key */ + mp_int zero; - /* start at offset y=PACKET_SIZE */ - y = PACKET_SIZE; - - /* output key type */ - out[y++] = type; - - /* output modulus */ - OUTPUT_BIGNUM(&key->N, out, y, z); - - /* output public key */ - OUTPUT_BIGNUM(&key->e, out, y, z); - - if (type == PK_PRIVATE || type == PK_PRIVATE_OPTIMIZED) { - OUTPUT_BIGNUM(&key->d, out, y, z); + /* first INTEGER == 0 to signify two-prime RSA */ + if ((err = mp_init(&zero)) != MP_OKAY) { + return mpi_to_ltc_error(err); + } + + /* output is + Version, n, e, d, p, q, d mod (p-1), d mod (q - 1), 1/q mod p + */ + err = der_put_multi_integer(out, outlen, &zero, &key->N, &key->e, + &key->d, &key->p, &key->q, &key->dP, + &key->dQ, &key->qP, NULL); + + /* clear zero and return */ + mp_clear(&zero); + return err; + } else { + /* public key */ + return der_put_multi_integer(out, outlen, &key->N, &key->e, NULL); } - - if (type == PK_PRIVATE_OPTIMIZED) { - OUTPUT_BIGNUM(&key->dQ, out, y, z); - OUTPUT_BIGNUM(&key->dP, out, y, z); - OUTPUT_BIGNUM(&key->pQ, out, y, z); - OUTPUT_BIGNUM(&key->qP, out, y, z); - OUTPUT_BIGNUM(&key->p, out, y, z); - OUTPUT_BIGNUM(&key->q, out, y, z); - } - - /* store packet header */ - packet_store_header(out, PACKET_SECT_RSA, PACKET_SUB_KEY); - - /* copy to the user buffer */ - *outlen = y; - - /* clear stack and return */ - return CRYPT_OK; } #endif /* MRSA */ diff --git a/rsa_exptmod.c b/rsa_exptmod.c index e94fad7..2eebd86 100644 --- a/rsa_exptmod.c +++ b/rsa_exptmod.c @@ -35,7 +35,7 @@ int rsa_exptmod(const unsigned char *in, unsigned long inlen, } /* is the key of the right type for the operation? */ - if (which == PK_PRIVATE && (key->type != PK_PRIVATE && key->type != PK_PRIVATE_OPTIMIZED)) { + if (which == PK_PRIVATE && (key->type != PK_PRIVATE)) { return CRYPT_PK_NOT_PRIVATE; } @@ -45,7 +45,7 @@ int rsa_exptmod(const unsigned char *in, unsigned long inlen, } /* init and copy into tmp */ - if ((err = mp_init_multi(&tmp, &tmpa, &tmpb, NULL)) != MP_OKAY) { goto error; } + if ((err = mp_init_multi(&tmp, &tmpa, &tmpb, NULL)) != MP_OKAY) { return mpi_to_ltc_error(err); } if ((err = mp_read_unsigned_bin(&tmp, (unsigned char *)in, (int)inlen)) != MP_OKAY) { goto error; } /* sanity check on the input */ @@ -55,24 +55,23 @@ int rsa_exptmod(const unsigned char *in, unsigned long inlen, } /* are we using the private exponent and is the key optimized? */ - if (which == PK_PRIVATE && key->type == PK_PRIVATE_OPTIMIZED) { + if (which == PK_PRIVATE) { /* tmpa = tmp^dP mod p */ if ((err = tim_exptmod(prng, prng_idx, &tmp, &key->e, &key->dP, &key->p, &tmpa)) != MP_OKAY) { goto error; } /* tmpb = tmp^dQ mod q */ if ((err = tim_exptmod(prng, prng_idx, &tmp, &key->e, &key->dQ, &key->q, &tmpb)) != MP_OKAY) { goto error; } - /* tmp = tmpa*qP + tmpb*pQ mod N */ - if ((err = mp_mul(&tmpa, &key->qP, &tmpa)) != MP_OKAY) { goto error; } - if ((err = mp_mul(&tmpb, &key->pQ, &tmpb)) != MP_OKAY) { goto error; } - if ((err = mp_addmod(&tmpa, &tmpb, &key->N, &tmp)) != MP_OKAY) { goto error; } + /* tmp = (tmpa - tmpb) * qInv (mod p) */ + if ((err = mp_sub(&tmpa, &tmpb, &tmp)) != MP_OKAY) { goto error; } + if ((err = mp_mulmod(&tmp, &key->qP, &key->p, &tmp)) != MP_OKAY) { goto error; } + + /* tmp = tmpb + q * tmp */ + if ((err = mp_mul(&tmp, &key->q, &tmp)) != MP_OKAY) { goto error; } + if ((err = mp_add(&tmp, &tmpb, &tmp)) != MP_OKAY) { goto error; } } else { /* exptmod it */ - if (which == PK_PRIVATE) { - if ((err = tim_exptmod(prng, prng_idx, &tmp, &key->e, &key->d, &key->N, &tmp)) != MP_OKAY) { goto error; } - } else { - if ((err = mp_exptmod(&tmp, &key->e, &key->N, &tmp)) != MP_OKAY) { goto error; } - } + if ((err = mp_exptmod(&tmp, &key->e, &key->N, &tmp)) != MP_OKAY) { goto error; } } /* read it back */ diff --git a/rsa_free.c b/rsa_free.c index c97242b..4562788 100644 --- a/rsa_free.c +++ b/rsa_free.c @@ -18,7 +18,7 @@ void rsa_free(rsa_key *key) { _ARGCHK(key != NULL); mp_clear_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, - &key->qP, &key->pQ, &key->p, &key->q, NULL); + &key->qP, &key->p, &key->q, NULL); } #endif diff --git a/rsa_import.c b/rsa_import.c index deffc38..02b4ca8 100644 --- a/rsa_import.c +++ b/rsa_import.c @@ -13,67 +13,55 @@ #ifdef MRSA +/* import an RSAPublicKey or RSAPrivateKey [two-prime only, defined in PKCS #1 v2.1] */ int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key) { - unsigned long x, y; + unsigned long x; int err; _ARGCHK(in != NULL); _ARGCHK(key != NULL); - /* 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 ((err = mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, &key->qP, - &key->pQ, &key->p, &key->q, NULL)) != MP_OKAY) { + &key->p, &key->q, NULL)) != MP_OKAY) { return mpi_to_ltc_error(err); } - /* get key type */ - y = PACKET_SIZE; - key->type = (int)in[y++]; - - /* load the modulus */ - INPUT_BIGNUM(&key->N, in, x, y, inlen); - - /* load public exponent */ - INPUT_BIGNUM(&key->e, in, x, y, inlen); - - /* get private exponent */ - if (key->type == PK_PRIVATE || key->type == PK_PRIVATE_OPTIMIZED) { - INPUT_BIGNUM(&key->d, in, x, y, inlen); + /* read first number, it's either N or 0 [0 == private key] */ + x = inlen; + if ((err = der_get_multi_integer(in, &x, &key->N, NULL)) != CRYPT_OK) { + goto __ERR; } - /* get CRT private data if required */ - if (key->type == PK_PRIVATE_OPTIMIZED) { - INPUT_BIGNUM(&key->dQ, in, x, y, inlen); - INPUT_BIGNUM(&key->dP, in, x, y, inlen); - INPUT_BIGNUM(&key->pQ, in, x, y, inlen); - INPUT_BIGNUM(&key->qP, in, x, y, inlen); - INPUT_BIGNUM(&key->p, in, x, y, inlen); - INPUT_BIGNUM(&key->q, in, x, y, inlen); - } + /* advance */ + inlen -= x; + in += x; - /* 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); - } - if (key->type != PK_PRIVATE && key->type != PK_PRIVATE_OPTIMIZED) { - mp_clear(&key->d); - } + if (mp_cmp_d(&key->N, 0) == MP_EQ) { + /* it's a private key */ + if ((err = der_get_multi_integer(in, &inlen, &key->N, &key->e, + &key->d, &key->p, &key->q, &key->dP, + &key->dQ, &key->qP, NULL)) != CRYPT_OK) { + goto __ERR; + } + key->type = PK_PRIVATE; + } else { + /* it's a public key and we lack e */ + if ((err = der_get_multi_integer(in, &inlen, &key->e, NULL)) != CRYPT_OK) { + goto __ERR; + } + + /* free up some ram */ + mp_clear_multi(&key->p, &key->q, &key->qP, &key->dP, &key->dQ, NULL); + + key->type = PK_PUBLIC; + } return CRYPT_OK; -error: +__ERR: mp_clear_multi(&key->d, &key->e, &key->N, &key->dQ, &key->dP, - &key->pQ, &key->qP, &key->p, &key->q, NULL); + &key->qP, &key->p, &key->q, NULL); return err; } diff --git a/rsa_make_key.c b/rsa_make_key.c index ded68cf..fc95450 100644 --- a/rsa_make_key.c +++ b/rsa_make_key.c @@ -61,7 +61,7 @@ int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key) /* make key */ if ((err = mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, - &key->qP, &key->pQ, &key->p, &key->q, NULL)) != MP_OKAY) { + &key->qP, &key->p, &key->q, NULL)) != MP_OKAY) { goto error; } @@ -73,15 +73,9 @@ int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key) /* find d mod q-1 and d mod p-1 */ if ((err = mp_sub_d(&p, 1, &tmp1)) != MP_OKAY) { goto error2; } /* tmp1 = q-1 */ if ((err = mp_sub_d(&q, 1, &tmp2)) != MP_OKAY) { goto error2; } /* tmp2 = p-1 */ - if ((err = mp_mod(&key->d, &tmp1, &key->dP)) != MP_OKAY) { goto error2; } /* dP = d mod p-1 */ if ((err = mp_mod(&key->d, &tmp2, &key->dQ)) != MP_OKAY) { goto error2; } /* dQ = d mod q-1 */ - if ((err = mp_invmod(&q, &p, &key->qP)) != MP_OKAY) { goto error2; } /* qP = 1/q mod p */ - if ((err = mp_mulmod(&key->qP, &q, &key->N, &key->qP)) != MP_OKAY) { goto error2; } /* qP = q * (1/q mod p) mod N */ - - if ((err = mp_invmod(&p, &q, &key->pQ)) != MP_OKAY) { goto error2; } /* pQ = 1/p mod q */ - if ((err = mp_mulmod(&key->pQ, &p, &key->N, &key->pQ)) != MP_OKAY) { goto error2; } /* pQ = p * (1/p mod q) mod N */ if ((err = mp_copy(&p, &key->p)) != MP_OKAY) { goto error2; } if ((err = mp_copy(&q, &key->q)) != MP_OKAY) { goto error2; } @@ -93,19 +87,18 @@ int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key) if ((err = mp_shrink(&key->dQ)) != MP_OKAY) { goto error2; } if ((err = mp_shrink(&key->dP)) != MP_OKAY) { goto error2; } if ((err = mp_shrink(&key->qP)) != MP_OKAY) { goto error2; } - if ((err = mp_shrink(&key->pQ)) != MP_OKAY) { goto error2; } if ((err = mp_shrink(&key->p)) != MP_OKAY) { goto error2; } if ((err = mp_shrink(&key->q)) != MP_OKAY) { goto error2; } /* set key type (in this case it's CRT optimized) */ - key->type = PK_PRIVATE_OPTIMIZED; + key->type = PK_PRIVATE; /* return ok and free temps */ err = CRYPT_OK; goto done; error2: mp_clear_multi(&key->d, &key->e, &key->N, &key->dQ, &key->dP, - &key->qP, &key->pQ, &key->p, &key->q, NULL); + &key->qP, &key->p, &key->q, NULL); error: err = mpi_to_ltc_error(err); done: diff --git a/sha1.c b/sha1.c index 77700f6..d6e57c3 100644 --- a/sha1.c +++ b/sha1.c @@ -38,9 +38,9 @@ const struct _hash_descriptor sha1_desc = #define F3(x,y,z) (x ^ y ^ z) #ifdef CLEAN_STACK -static void _sha1_compress(hash_state *md, unsigned char *buf) +static int _sha1_compress(hash_state *md, unsigned char *buf) #else -static void sha1_compress(hash_state *md, unsigned char *buf) +static int sha1_compress(hash_state *md, unsigned char *buf) #endif { ulong32 a,b,c,d,e,W[80],i; @@ -139,17 +139,21 @@ static void sha1_compress(hash_state *md, unsigned char *buf) md->sha1.state[2] = md->sha1.state[2] + c; md->sha1.state[3] = md->sha1.state[3] + d; md->sha1.state[4] = md->sha1.state[4] + e; + + return CRYPT_OK; } #ifdef CLEAN_STACK -static void sha1_compress(hash_state *md, unsigned char *buf) +static int sha1_compress(hash_state *md, unsigned char *buf) { - _sha1_compress(md, buf); + int err; + err = _sha1_compress(md, buf); burn_stack(sizeof(ulong32) * 87); + return err; } #endif -void sha1_init(hash_state * md) +int sha1_init(hash_state * md) { _ARGCHK(md != NULL); md->sha1.state[0] = 0x67452301UL; @@ -159,6 +163,7 @@ void sha1_init(hash_state * md) md->sha1.state[4] = 0xc3d2e1f0UL; md->sha1.curlen = 0; md->sha1.length = 0; + return CRYPT_OK; } HASH_PROCESS(sha1_process, sha1_compress, sha1, 64) diff --git a/sha224.c b/sha224.c index fb9f09e..2b25ff0 100644 --- a/sha224.c +++ b/sha224.c @@ -28,7 +28,7 @@ const struct _hash_descriptor sha224_desc = }; /* init the sha256 er... sha224 state ;-) */ -void sha224_init(hash_state * md) +int sha224_init(hash_state * md) { _ARGCHK(md != NULL); @@ -42,6 +42,7 @@ void sha224_init(hash_state * md) md->sha256.state[5] = 0x68581511UL; md->sha256.state[6] = 0x64f98fa7UL; md->sha256.state[7] = 0xbefa4fa4UL; + return CRYPT_OK; } int sha224_done(hash_state * md, unsigned char *hash) diff --git a/sha256.c b/sha256.c index 02bce05..b918e3f 100644 --- a/sha256.c +++ b/sha256.c @@ -66,9 +66,9 @@ static const unsigned long K[64] = { /* compress 512-bits */ #ifdef CLEAN_STACK -static void _sha256_compress(hash_state * md, unsigned char *buf) +static int _sha256_compress(hash_state * md, unsigned char *buf) #else -static void sha256_compress(hash_state * md, unsigned char *buf) +static int sha256_compress(hash_state * md, unsigned char *buf) #endif { ulong32 S[8], W[64], t0, t1; @@ -185,19 +185,21 @@ static void sha256_compress(hash_state * md, unsigned char *buf) for (i = 0; i < 8; i++) { md->sha256.state[i] = md->sha256.state[i] + S[i]; } - + return CRYPT_OK; } #ifdef CLEAN_STACK -static void sha256_compress(hash_state * md, unsigned char *buf) +static int sha256_compress(hash_state * md, unsigned char *buf) { - _sha256_compress(md, buf); + int err; + err = _sha256_compress(md, buf); burn_stack(sizeof(ulong32) * 74); + return err; } #endif /* init the sha256 state */ -void sha256_init(hash_state * md) +int sha256_init(hash_state * md) { _ARGCHK(md != NULL); @@ -211,6 +213,7 @@ void sha256_init(hash_state * md) md->sha256.state[5] = 0x9B05688CUL; md->sha256.state[6] = 0x1F83D9ABUL; md->sha256.state[7] = 0x5BE0CD19UL; + return CRYPT_OK; } HASH_PROCESS(sha256_process, sha256_compress, sha256, 64) diff --git a/sha384.c b/sha384.c index d771fc8..190e8ca 100644 --- a/sha384.c +++ b/sha384.c @@ -30,7 +30,7 @@ const struct _hash_descriptor sha384_desc = &sha384_test }; -void sha384_init(hash_state * md) +int sha384_init(hash_state * md) { _ARGCHK(md != NULL); @@ -44,6 +44,7 @@ void sha384_init(hash_state * md) md->sha512.state[5] = CONST64(0x8eb44a8768581511); md->sha512.state[6] = CONST64(0xdb0c2e0d64f98fa7); md->sha512.state[7] = CONST64(0x47b5481dbefa4fa4); + return CRYPT_OK; } int sha384_done(hash_state * md, unsigned char *hash) diff --git a/sha512.c b/sha512.c index 9b5ddad..baf27cf 100644 --- a/sha512.c +++ b/sha512.c @@ -90,9 +90,9 @@ CONST64(0x5fcb6fab3ad6faec), CONST64(0x6c44198c4a475817) /* compress 1024-bits */ #ifdef CLEAN_STACK -static void _sha512_compress(hash_state * md, unsigned char *buf) +static int _sha512_compress(hash_state * md, unsigned char *buf) #else -static void sha512_compress(hash_state * md, unsigned char *buf) +static int sha512_compress(hash_state * md, unsigned char *buf) #endif { ulong64 S[8], W[80], t0, t1; @@ -151,22 +151,25 @@ static void sha512_compress(hash_state * md, unsigned char *buf) for (i = 0; i < 8; i++) { md->sha512.state[i] = md->sha512.state[i] + S[i]; } + + return CRYPT_OK; } /* compress 1024-bits */ #ifdef CLEAN_STACK -static void sha512_compress(hash_state * md, unsigned char *buf) +static int sha512_compress(hash_state * md, unsigned char *buf) { - _sha512_compress(md, buf); + int err; + err = _sha512_compress(md, buf); burn_stack(sizeof(ulong64) * 90 + sizeof(int)); + return err; } #endif /* init the sha512 state */ -void sha512_init(hash_state * md) +int sha512_init(hash_state * md) { _ARGCHK(md != NULL); - md->sha512.curlen = 0; md->sha512.length = 0; md->sha512.state[0] = CONST64(0x6a09e667f3bcc908); @@ -177,6 +180,7 @@ void sha512_init(hash_state * md) md->sha512.state[5] = CONST64(0x9b05688c2b3e6c1f); md->sha512.state[6] = CONST64(0x1f83d9abfb41bd6b); md->sha512.state[7] = CONST64(0x5be0cd19137e2179); + return CRYPT_OK; } HASH_PROCESS(sha512_process, sha512_compress, sha512, 128) diff --git a/sober128.c b/sober128.c index dee7471..bc00748 100644 --- a/sober128.c +++ b/sober128.c @@ -438,7 +438,7 @@ int sober128_test(void) } return CRYPT_OK; #endif -}; +} #endif diff --git a/tiger.c b/tiger.c index 06eb384..3235953 100644 --- a/tiger.c +++ b/tiger.c @@ -606,9 +606,9 @@ static void key_schedule(ulong64 *x) } #ifdef CLEAN_STACK -static void _tiger_compress(hash_state *md, unsigned char *buf) +static int _tiger_compress(hash_state *md, unsigned char *buf) #else -static void tiger_compress(hash_state *md, unsigned char *buf) +static int tiger_compress(hash_state *md, unsigned char *buf) #endif { ulong64 a, b, c, x[8]; @@ -632,17 +632,21 @@ static void tiger_compress(hash_state *md, unsigned char *buf) md->tiger.state[0] = a ^ md->tiger.state[0]; md->tiger.state[1] = b - md->tiger.state[1]; md->tiger.state[2] = c + md->tiger.state[2]; + + return CRYPT_OK; } #ifdef CLEAN_STACK -static void tiger_compress(hash_state *md, unsigned char *buf) +static int tiger_compress(hash_state *md, unsigned char *buf) { - _tiger_compress(md, buf); + int err; + err = _tiger_compress(md, buf); burn_stack(sizeof(ulong64) * 11 + sizeof(unsigned long)); + return err; } #endif -void tiger_init(hash_state *md) +int tiger_init(hash_state *md) { _ARGCHK(md != NULL); md->tiger.state[0] = CONST64(0x0123456789ABCDEF); @@ -650,6 +654,7 @@ void tiger_init(hash_state *md) md->tiger.state[2] = CONST64(0xF096A5B4C3B2E187); md->tiger.curlen = 0; md->tiger.length = 0; + return CRYPT_OK; } HASH_PROCESS(tiger_process, tiger_compress, tiger, 64) diff --git a/tommath_class.h b/tommath_class.h new file mode 100644 index 0000000..c94e8e0 --- /dev/null +++ b/tommath_class.h @@ -0,0 +1,955 @@ +#if !(defined(LTM1) && defined(LTM2) && defined(LTM3)) +#if defined(LTM2) +#define LTM3 +#endif +#if defined(LTM1) +#define LTM2 +#endif +#define LTM1 + +#if defined(LTM_ALL) +#define BN_ERROR_C +#define BN_FAST_MP_INVMOD_C +#define BN_FAST_MP_MONTGOMERY_REDUCE_C +#define BN_FAST_S_MP_MUL_DIGS_C +#define BN_FAST_S_MP_MUL_HIGH_DIGS_C +#define BN_FAST_S_MP_SQR_C +#define BN_MP_2EXPT_C +#define BN_MP_ABS_C +#define BN_MP_ADD_C +#define BN_MP_ADD_D_C +#define BN_MP_ADDMOD_C +#define BN_MP_AND_C +#define BN_MP_CLAMP_C +#define BN_MP_CLEAR_C +#define BN_MP_CLEAR_MULTI_C +#define BN_MP_CMP_C +#define BN_MP_CMP_D_C +#define BN_MP_CMP_MAG_C +#define BN_MP_CNT_LSB_C +#define BN_MP_COPY_C +#define BN_MP_COUNT_BITS_C +#define BN_MP_DIV_C +#define BN_MP_DIV_2_C +#define BN_MP_DIV_2D_C +#define BN_MP_DIV_3_C +#define BN_MP_DIV_D_C +#define BN_MP_DR_IS_MODULUS_C +#define BN_MP_DR_REDUCE_C +#define BN_MP_DR_SETUP_C +#define BN_MP_EXCH_C +#define BN_MP_EXPT_D_C +#define BN_MP_EXPTMOD_C +#define BN_MP_EXPTMOD_FAST_C +#define BN_MP_EXTEUCLID_C +#define BN_MP_FREAD_C +#define BN_MP_FWRITE_C +#define BN_MP_GCD_C +#define BN_MP_GET_INT_C +#define BN_MP_GROW_C +#define BN_MP_INIT_C +#define BN_MP_INIT_COPY_C +#define BN_MP_INIT_MULTI_C +#define BN_MP_INIT_SET_C +#define BN_MP_INIT_SET_INT_C +#define BN_MP_INIT_SIZE_C +#define BN_MP_INVMOD_C +#define BN_MP_INVMOD_SLOW_C +#define BN_MP_IS_SQUARE_C +#define BN_MP_JACOBI_C +#define BN_MP_KARATSUBA_MUL_C +#define BN_MP_KARATSUBA_SQR_C +#define BN_MP_LCM_C +#define BN_MP_LSHD_C +#define BN_MP_MOD_C +#define BN_MP_MOD_2D_C +#define BN_MP_MOD_D_C +#define BN_MP_MONTGOMERY_CALC_NORMALIZATION_C +#define BN_MP_MONTGOMERY_REDUCE_C +#define BN_MP_MONTGOMERY_SETUP_C +#define BN_MP_MUL_C +#define BN_MP_MUL_2_C +#define BN_MP_MUL_2D_C +#define BN_MP_MUL_D_C +#define BN_MP_MULMOD_C +#define BN_MP_N_ROOT_C +#define BN_MP_NEG_C +#define BN_MP_OR_C +#define BN_MP_PRIME_FERMAT_C +#define BN_MP_PRIME_IS_DIVISIBLE_C +#define BN_MP_PRIME_IS_PRIME_C +#define BN_MP_PRIME_MILLER_RABIN_C +#define BN_MP_PRIME_NEXT_PRIME_C +#define BN_MP_PRIME_RABIN_MILLER_TRIALS_C +#define BN_MP_PRIME_RANDOM_EX_C +#define BN_MP_RADIX_SIZE_C +#define BN_MP_RADIX_SMAP_C +#define BN_MP_RAND_C +#define BN_MP_READ_RADIX_C +#define BN_MP_READ_SIGNED_BIN_C +#define BN_MP_READ_UNSIGNED_BIN_C +#define BN_MP_REDUCE_C +#define BN_MP_REDUCE_2K_C +#define BN_MP_REDUCE_2K_SETUP_C +#define BN_MP_REDUCE_IS_2K_C +#define BN_MP_REDUCE_SETUP_C +#define BN_MP_RSHD_C +#define BN_MP_SET_C +#define BN_MP_SET_INT_C +#define BN_MP_SHRINK_C +#define BN_MP_SIGNED_BIN_SIZE_C +#define BN_MP_SQR_C +#define BN_MP_SQRMOD_C +#define BN_MP_SQRT_C +#define BN_MP_SUB_C +#define BN_MP_SUB_D_C +#define BN_MP_SUBMOD_C +#define BN_MP_TO_SIGNED_BIN_C +#define BN_MP_TO_UNSIGNED_BIN_C +#define BN_MP_TOOM_MUL_C +#define BN_MP_TOOM_SQR_C +#define BN_MP_TORADIX_C +#define BN_MP_TORADIX_N_C +#define BN_MP_UNSIGNED_BIN_SIZE_C +#define BN_MP_XOR_C +#define BN_MP_ZERO_C +#define BN_PRIME_TAB_C +#define BN_REVERSE_C +#define BN_S_MP_ADD_C +#define BN_S_MP_EXPTMOD_C +#define BN_S_MP_MUL_DIGS_C +#define BN_S_MP_MUL_HIGH_DIGS_C +#define BN_S_MP_SQR_C +#define BN_S_MP_SUB_C +#define BNCORE_C +#endif + +#if defined(BN_ERROR_C) + #define BN_MP_ERROR_TO_STRING_C +#endif + +#if defined(BN_FAST_MP_INVMOD_C) + #define BN_MP_ISEVEN_C + #define BN_MP_INIT_MULTI_C + #define BN_MP_COPY_C + #define BN_MP_ABS_C + #define BN_MP_SET_C + #define BN_MP_DIV_2_C + #define BN_MP_ISODD_C + #define BN_MP_SUB_C + #define BN_MP_CMP_C + #define BN_MP_ISZERO_C + #define BN_MP_CMP_D_C + #define BN_MP_ADD_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_MULTI_C +#endif + +#if defined(BN_FAST_MP_MONTGOMERY_REDUCE_C) + #define BN_MP_MONTGOMERY_REDUCE_C + #define BN_MP_GROW_C + #define BN_MP_RSHD_C + #define BN_MP_CLAMP_C + #define BN_MP_CMP_MAG_C + #define BN_S_MP_SUB_C +#endif + +#if defined(BN_FAST_S_MP_MUL_DIGS_C) + #define BN_MP_GROW_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_FAST_S_MP_MUL_HIGH_DIGS_C) + #define BN_FAST_S_MP_MUL_DIGS_C + #define BN_MP_GROW_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_FAST_S_MP_SQR_C) + #define BN_MP_GROW_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_2EXPT_C) + #define BN_MP_ZERO_C + #define BN_MP_GROW_C +#endif + +#if defined(BN_MP_ABS_C) + #define BN_MP_COPY_C +#endif + +#if defined(BN_MP_ADD_C) + #define BN_S_MP_ADD_C + #define BN_MP_CMP_MAG_C + #define BN_S_MP_SUB_C +#endif + +#if defined(BN_MP_ADD_D_C) + #define BN_MP_GROW_C + #define BN_MP_SUB_D_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_ADDMOD_C) + #define BN_MP_INIT_C + #define BN_MP_ADD_C + #define BN_MP_CLEAR_C + #define BN_MP_MOD_C +#endif + +#if defined(BN_MP_AND_C) + #define BN_MP_INIT_COPY_C + #define BN_MP_CLAMP_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_CLAMP_C) +#endif + +#if defined(BN_MP_CLEAR_C) +#endif + +#if defined(BN_MP_CLEAR_MULTI_C) + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_CMP_C) + #define BN_MP_CMP_MAG_C +#endif + +#if defined(BN_MP_CMP_D_C) +#endif + +#if defined(BN_MP_CMP_MAG_C) +#endif + +#if defined(BN_MP_CNT_LSB_C) + #define BN_MP_ISZERO_C +#endif + +#if defined(BN_MP_COPY_C) + #define BN_MP_GROW_C +#endif + +#if defined(BN_MP_COUNT_BITS_C) +#endif + +#if defined(BN_MP_DIV_C) + #define BN_MP_ISZERO_C + #define BN_MP_CMP_MAG_C + #define BN_MP_COPY_C + #define BN_MP_ZERO_C + #define BN_MP_INIT_MULTI_C + #define BN_MP_SET_C + #define BN_MP_COUNT_BITS_C + #define BN_MP_MUL_2D_C + #define BN_MP_CMP_C + #define BN_MP_SUB_C + #define BN_MP_ADD_C + #define BN_MP_DIV_2D_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_MULTI_C + #define BN_MP_INIT_SIZE_C + #define BN_MP_INIT_C + #define BN_MP_INIT_COPY_C + #define BN_MP_LSHD_C + #define BN_MP_RSHD_C + #define BN_MP_MUL_D_C + #define BN_MP_CLAMP_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_DIV_2_C) + #define BN_MP_GROW_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_DIV_2D_C) + #define BN_MP_COPY_C + #define BN_MP_ZERO_C + #define BN_MP_INIT_C + #define BN_MP_MOD_2D_C + #define BN_MP_CLEAR_C + #define BN_MP_RSHD_C + #define BN_MP_CLAMP_C + #define BN_MP_EXCH_C +#endif + +#if defined(BN_MP_DIV_3_C) + #define BN_MP_INIT_SIZE_C + #define BN_MP_CLAMP_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_DIV_D_C) + #define BN_MP_ISZERO_C + #define BN_MP_COPY_C + #define BN_MP_DIV_2D_C + #define BN_MP_DIV_3_C + #define BN_MP_INIT_SIZE_C + #define BN_MP_CLAMP_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_DR_IS_MODULUS_C) +#endif + +#if defined(BN_MP_DR_REDUCE_C) + #define BN_MP_GROW_C + #define BN_MP_CLAMP_C + #define BN_MP_CMP_MAG_C + #define BN_S_MP_SUB_C +#endif + +#if defined(BN_MP_DR_SETUP_C) +#endif + +#if defined(BN_MP_EXCH_C) +#endif + +#if defined(BN_MP_EXPT_D_C) + #define BN_MP_INIT_COPY_C + #define BN_MP_SET_C + #define BN_MP_SQR_C + #define BN_MP_CLEAR_C + #define BN_MP_MUL_C +#endif + +#if defined(BN_MP_EXPTMOD_C) + #define BN_MP_INIT_C + #define BN_MP_INVMOD_C + #define BN_MP_CLEAR_C + #define BN_MP_ABS_C + #define BN_MP_CLEAR_MULTI_C + #define BN_MP_DR_IS_MODULUS_C + #define BN_MP_REDUCE_IS_2K_C + #define BN_MP_ISODD_C + #define BN_MP_EXPTMOD_FAST_C + #define BN_S_MP_EXPTMOD_C +#endif + +#if defined(BN_MP_EXPTMOD_FAST_C) + #define BN_MP_COUNT_BITS_C + #define BN_MP_INIT_C + #define BN_MP_CLEAR_C + #define BN_MP_MONTGOMERY_SETUP_C + #define BN_FAST_MP_MONTGOMERY_REDUCE_C + #define BN_MP_MONTGOMERY_REDUCE_C + #define BN_MP_DR_SETUP_C + #define BN_MP_DR_REDUCE_C + #define BN_MP_REDUCE_2K_SETUP_C + #define BN_MP_REDUCE_2K_C + #define BN_MP_MONTGOMERY_CALC_NORMALIZATION_C + #define BN_MP_MULMOD_C + #define BN_MP_SET_C + #define BN_MP_MOD_C + #define BN_MP_COPY_C + #define BN_MP_SQR_C + #define BN_MP_MUL_C + #define BN_MP_EXCH_C +#endif + +#if defined(BN_MP_EXTEUCLID_C) + #define BN_MP_INIT_MULTI_C + #define BN_MP_SET_C + #define BN_MP_COPY_C + #define BN_MP_ISZERO_C + #define BN_MP_DIV_C + #define BN_MP_MUL_C + #define BN_MP_SUB_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_MULTI_C +#endif + +#if defined(BN_MP_FREAD_C) + #define BN_MP_ZERO_C + #define BN_MP_S_RMAP_C + #define BN_MP_MUL_D_C + #define BN_MP_ADD_D_C + #define BN_MP_CMP_D_C +#endif + +#if defined(BN_MP_FWRITE_C) + #define BN_MP_RADIX_SIZE_C + #define BN_MP_TORADIX_C +#endif + +#if defined(BN_MP_GCD_C) + #define BN_MP_ISZERO_C + #define BN_MP_ABS_C + #define BN_MP_ZERO_C + #define BN_MP_INIT_COPY_C + #define BN_MP_CNT_LSB_C + #define BN_MP_DIV_2D_C + #define BN_MP_CMP_MAG_C + #define BN_MP_EXCH_C + #define BN_S_MP_SUB_C + #define BN_MP_MUL_2D_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_GET_INT_C) +#endif + +#if defined(BN_MP_GROW_C) +#endif + +#if defined(BN_MP_INIT_C) +#endif + +#if defined(BN_MP_INIT_COPY_C) + #define BN_MP_COPY_C +#endif + +#if defined(BN_MP_INIT_MULTI_C) + #define BN_MP_ERR_C + #define BN_MP_INIT_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_INIT_SET_C) + #define BN_MP_INIT_C + #define BN_MP_SET_C +#endif + +#if defined(BN_MP_INIT_SET_INT_C) + #define BN_MP_INIT_C + #define BN_MP_SET_INT_C +#endif + +#if defined(BN_MP_INIT_SIZE_C) + #define BN_MP_INIT_C +#endif + +#if defined(BN_MP_INVMOD_C) + #define BN_MP_ISZERO_C + #define BN_MP_ISODD_C + #define BN_FAST_MP_INVMOD_C + #define BN_MP_INVMOD_SLOW_C +#endif + +#if defined(BN_MP_INVMOD_SLOW_C) + #define BN_MP_ISZERO_C + #define BN_MP_INIT_MULTI_C + #define BN_MP_COPY_C + #define BN_MP_ISEVEN_C + #define BN_MP_SET_C + #define BN_MP_DIV_2_C + #define BN_MP_ISODD_C + #define BN_MP_ADD_C + #define BN_MP_SUB_C + #define BN_MP_CMP_C + #define BN_MP_CMP_D_C + #define BN_MP_CMP_MAG_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_MULTI_C +#endif + +#if defined(BN_MP_IS_SQUARE_C) + #define BN_MP_MOD_D_C + #define BN_MP_INIT_SET_INT_C + #define BN_MP_MOD_C + #define BN_MP_GET_INT_C + #define BN_MP_SQRT_C + #define BN_MP_SQR_C + #define BN_MP_CMP_MAG_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_JACOBI_C) + #define BN_MP_CMP_D_C + #define BN_MP_ISZERO_C + #define BN_MP_INIT_COPY_C + #define BN_MP_CNT_LSB_C + #define BN_MP_DIV_2D_C + #define BN_MP_MOD_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_KARATSUBA_MUL_C) + #define BN_MP_MUL_C + #define BN_MP_INIT_SIZE_C + #define BN_MP_CLAMP_C + #define BN_MP_SUB_C + #define BN_MP_ADD_C + #define BN_MP_LSHD_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_KARATSUBA_SQR_C) + #define BN_MP_KARATSUBA_MUL_C + #define BN_MP_INIT_SIZE_C + #define BN_MP_CLAMP_C + #define BN_MP_SQR_C + #define BN_MP_SUB_C + #define BN_S_MP_ADD_C + #define BN_MP_LSHD_C + #define BN_MP_ADD_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_LCM_C) + #define BN_MP_INIT_MULTI_C + #define BN_MP_GCD_C + #define BN_MP_CMP_MAG_C + #define BN_MP_DIV_C + #define BN_MP_MUL_C + #define BN_MP_CLEAR_MULTI_C +#endif + +#if defined(BN_MP_LSHD_C) + #define BN_MP_GROW_C + #define BN_MP_RSHD_C +#endif + +#if defined(BN_MP_MOD_C) + #define BN_MP_INIT_C + #define BN_MP_DIV_C + #define BN_MP_CLEAR_C + #define BN_MP_ADD_C + #define BN_MP_EXCH_C +#endif + +#if defined(BN_MP_MOD_2D_C) + #define BN_MP_ZERO_C + #define BN_MP_COPY_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_MOD_D_C) + #define BN_MP_DIV_D_C +#endif + +#if defined(BN_MP_MONTGOMERY_CALC_NORMALIZATION_C) + #define BN_MP_COUNT_BITS_C + #define BN_MP_2EXPT_C + #define BN_MP_SET_C + #define BN_MP_MUL_2_C + #define BN_MP_CMP_MAG_C + #define BN_S_MP_SUB_C +#endif + +#if defined(BN_MP_MONTGOMERY_REDUCE_C) + #define BN_MP_MUL_C + #define BN_FAST_MP_MONTGOMERY_REDUCE_C + #define BN_MP_GROW_C + #define BN_MP_MONTGOMERY_SETUP_C + #define BN_MP_CLAMP_C + #define BN_MP_RSHD_C + #define BN_MP_CMP_MAG_C + #define BN_S_MP_SUB_C +#endif + +#if defined(BN_MP_MONTGOMERY_SETUP_C) +#endif + +#if defined(BN_MP_MUL_C) + #define BN_MP_TOOM_MUL_C + #define BN_MP_KARATSUBA_MUL_C + #define BN_FAST_S_MP_MUL_DIGS_C + #define BN_S_MP_MUL_C + #define BN_S_MP_MUL_DIGS_C +#endif + +#if defined(BN_MP_MUL_2_C) + #define BN_MP_GROW_C +#endif + +#if defined(BN_MP_MUL_2D_C) + #define BN_MP_COPY_C + #define BN_MP_GROW_C + #define BN_MP_LSHD_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_MUL_D_C) + #define BN_MP_GROW_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_MULMOD_C) + #define BN_MP_INIT_C + #define BN_MP_MUL_C + #define BN_MP_CLEAR_C + #define BN_MP_MOD_C +#endif + +#if defined(BN_MP_N_ROOT_C) + #define BN_MP_INIT_C + #define BN_MP_SET_C + #define BN_MP_COPY_C + #define BN_MP_EXPT_D_C + #define BN_MP_MUL_C + #define BN_MP_SUB_C + #define BN_MP_MUL_D_C + #define BN_MP_DIV_C + #define BN_MP_CMP_C + #define BN_MP_SUB_D_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_NEG_C) + #define BN_MP_COPY_C + #define BN_MP_ISZERO_C +#endif + +#if defined(BN_MP_OR_C) + #define BN_MP_INIT_COPY_C + #define BN_MP_CLAMP_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_PRIME_FERMAT_C) + #define BN_MP_CMP_D_C + #define BN_MP_INIT_C + #define BN_MP_EXPTMOD_C + #define BN_MP_CMP_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_PRIME_IS_DIVISIBLE_C) + #define BN_MP_MOD_D_C +#endif + +#if defined(BN_MP_PRIME_IS_PRIME_C) + #define BN_MP_CMP_D_C + #define BN_MP_PRIME_IS_DIVISIBLE_C + #define BN_MP_INIT_C + #define BN_MP_SET_C + #define BN_MP_PRIME_MILLER_RABIN_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_PRIME_MILLER_RABIN_C) + #define BN_MP_CMP_D_C + #define BN_MP_INIT_COPY_C + #define BN_MP_SUB_D_C + #define BN_MP_CNT_LSB_C + #define BN_MP_DIV_2D_C + #define BN_MP_EXPTMOD_C + #define BN_MP_CMP_C + #define BN_MP_SQRMOD_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_PRIME_NEXT_PRIME_C) + #define BN_MP_CMP_D_C + #define BN_MP_SET_C + #define BN_MP_SUB_D_C + #define BN_MP_ISEVEN_C + #define BN_MP_MOD_D_C + #define BN_MP_INIT_C + #define BN_MP_ADD_D_C + #define BN_MP_PRIME_MILLER_RABIN_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_PRIME_RABIN_MILLER_TRIALS_C) +#endif + +#if defined(BN_MP_PRIME_RANDOM_EX_C) + #define BN_MP_READ_UNSIGNED_BIN_C + #define BN_MP_PRIME_IS_PRIME_C + #define BN_MP_SUB_D_C + #define BN_MP_DIV_2_C + #define BN_MP_MUL_2_C + #define BN_MP_ADD_D_C +#endif + +#if defined(BN_MP_RADIX_SIZE_C) + #define BN_MP_COUNT_BITS_C + #define BN_MP_INIT_COPY_C + #define BN_MP_ISZERO_C + #define BN_MP_DIV_D_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_RADIX_SMAP_C) + #define BN_MP_S_RMAP_C +#endif + +#if defined(BN_MP_RAND_C) + #define BN_MP_ZERO_C + #define BN_MP_ADD_D_C + #define BN_MP_LSHD_C +#endif + +#if defined(BN_MP_READ_RADIX_C) + #define BN_MP_ZERO_C + #define BN_MP_S_RMAP_C + #define BN_MP_MUL_D_C + #define BN_MP_ADD_D_C + #define BN_MP_ISZERO_C +#endif + +#if defined(BN_MP_READ_SIGNED_BIN_C) + #define BN_MP_READ_UNSIGNED_BIN_C +#endif + +#if defined(BN_MP_READ_UNSIGNED_BIN_C) + #define BN_MP_GROW_C + #define BN_MP_ZERO_C + #define BN_MP_MUL_2D_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_REDUCE_C) + #define BN_MP_REDUCE_SETUP_C + #define BN_MP_INIT_COPY_C + #define BN_MP_RSHD_C + #define BN_MP_MUL_C + #define BN_S_MP_MUL_HIGH_DIGS_C + #define BN_MP_MOD_2D_C + #define BN_S_MP_MUL_DIGS_C + #define BN_MP_SUB_C + #define BN_MP_CMP_D_C + #define BN_MP_SET_C + #define BN_MP_LSHD_C + #define BN_MP_ADD_C + #define BN_MP_CMP_C + #define BN_S_MP_SUB_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_REDUCE_2K_C) + #define BN_MP_INIT_C + #define BN_MP_COUNT_BITS_C + #define BN_MP_DIV_2D_C + #define BN_MP_MUL_D_C + #define BN_S_MP_ADD_C + #define BN_MP_CMP_MAG_C + #define BN_S_MP_SUB_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_REDUCE_2K_SETUP_C) + #define BN_MP_INIT_C + #define BN_MP_COUNT_BITS_C + #define BN_MP_2EXPT_C + #define BN_MP_CLEAR_C + #define BN_S_MP_SUB_C +#endif + +#if defined(BN_MP_REDUCE_IS_2K_C) + #define BN_MP_REDUCE_2K_C + #define BN_MP_COUNT_BITS_C +#endif + +#if defined(BN_MP_REDUCE_SETUP_C) + #define BN_MP_2EXPT_C + #define BN_MP_DIV_C +#endif + +#if defined(BN_MP_RSHD_C) + #define BN_MP_ZERO_C +#endif + +#if defined(BN_MP_SET_C) + #define BN_MP_ZERO_C +#endif + +#if defined(BN_MP_SET_INT_C) + #define BN_MP_ZERO_C + #define BN_MP_MUL_2D_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_SHRINK_C) +#endif + +#if defined(BN_MP_SIGNED_BIN_SIZE_C) + #define BN_MP_UNSIGNED_BIN_SIZE_C +#endif + +#if defined(BN_MP_SQR_C) + #define BN_MP_TOOM_SQR_C + #define BN_MP_KARATSUBA_SQR_C + #define BN_FAST_S_MP_SQR_C + #define BN_S_MP_SQR_C +#endif + +#if defined(BN_MP_SQRMOD_C) + #define BN_MP_INIT_C + #define BN_MP_SQR_C + #define BN_MP_CLEAR_C + #define BN_MP_MOD_C +#endif + +#if defined(BN_MP_SQRT_C) + #define BN_MP_N_ROOT_C + #define BN_MP_ISZERO_C + #define BN_MP_ZERO_C + #define BN_MP_INIT_COPY_C + #define BN_MP_RSHD_C + #define BN_MP_DIV_C + #define BN_MP_ADD_C + #define BN_MP_DIV_2_C + #define BN_MP_CMP_MAG_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_SUB_C) + #define BN_S_MP_ADD_C + #define BN_MP_CMP_MAG_C + #define BN_S_MP_SUB_C +#endif + +#if defined(BN_MP_SUB_D_C) + #define BN_MP_GROW_C + #define BN_MP_ADD_D_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_SUBMOD_C) + #define BN_MP_INIT_C + #define BN_MP_SUB_C + #define BN_MP_CLEAR_C + #define BN_MP_MOD_C +#endif + +#if defined(BN_MP_TO_SIGNED_BIN_C) + #define BN_MP_TO_UNSIGNED_BIN_C +#endif + +#if defined(BN_MP_TO_UNSIGNED_BIN_C) + #define BN_MP_INIT_COPY_C + #define BN_MP_ISZERO_C + #define BN_MP_DIV_2D_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_TOOM_MUL_C) + #define BN_MP_INIT_MULTI_C + #define BN_MP_MOD_2D_C + #define BN_MP_COPY_C + #define BN_MP_RSHD_C + #define BN_MP_MUL_C + #define BN_MP_MUL_2_C + #define BN_MP_ADD_C + #define BN_MP_SUB_C + #define BN_MP_DIV_2_C + #define BN_MP_MUL_2D_C + #define BN_MP_MUL_D_C + #define BN_MP_DIV_3_C + #define BN_MP_LSHD_C + #define BN_MP_CLEAR_MULTI_C +#endif + +#if defined(BN_MP_TOOM_SQR_C) + #define BN_MP_INIT_MULTI_C + #define BN_MP_MOD_2D_C + #define BN_MP_COPY_C + #define BN_MP_RSHD_C + #define BN_MP_SQR_C + #define BN_MP_MUL_2_C + #define BN_MP_ADD_C + #define BN_MP_SUB_C + #define BN_MP_DIV_2_C + #define BN_MP_MUL_2D_C + #define BN_MP_MUL_D_C + #define BN_MP_DIV_3_C + #define BN_MP_LSHD_C + #define BN_MP_CLEAR_MULTI_C +#endif + +#if defined(BN_MP_TORADIX_C) + #define BN_MP_ISZERO_C + #define BN_MP_INIT_COPY_C + #define BN_MP_DIV_D_C + #define BN_MP_CLEAR_C + #define BN_MP_S_RMAP_C +#endif + +#if defined(BN_MP_TORADIX_N_C) + #define BN_MP_ISZERO_C + #define BN_MP_INIT_COPY_C + #define BN_MP_DIV_D_C + #define BN_MP_CLEAR_C + #define BN_MP_S_RMAP_C +#endif + +#if defined(BN_MP_UNSIGNED_BIN_SIZE_C) + #define BN_MP_COUNT_BITS_C +#endif + +#if defined(BN_MP_XOR_C) + #define BN_MP_INIT_COPY_C + #define BN_MP_CLAMP_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_ZERO_C) +#endif + +#if defined(BN_PRIME_TAB_C) +#endif + +#if defined(BN_REVERSE_C) +#endif + +#if defined(BN_S_MP_ADD_C) + #define BN_MP_GROW_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_S_MP_EXPTMOD_C) + #define BN_MP_COUNT_BITS_C + #define BN_MP_INIT_C + #define BN_MP_CLEAR_C + #define BN_MP_REDUCE_SETUP_C + #define BN_MP_MOD_C + #define BN_MP_COPY_C + #define BN_MP_SQR_C + #define BN_MP_REDUCE_C + #define BN_MP_MUL_C + #define BN_MP_SET_C + #define BN_MP_EXCH_C +#endif + +#if defined(BN_S_MP_MUL_DIGS_C) + #define BN_FAST_S_MP_MUL_DIGS_C + #define BN_MP_INIT_SIZE_C + #define BN_MP_CLAMP_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_S_MP_MUL_HIGH_DIGS_C) + #define BN_FAST_S_MP_MUL_HIGH_DIGS_C + #define BN_MP_INIT_SIZE_C + #define BN_MP_CLAMP_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_S_MP_SQR_C) + #define BN_MP_INIT_SIZE_C + #define BN_MP_CLAMP_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_S_MP_SUB_C) + #define BN_MP_GROW_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BNCORE_C) +#endif + +#ifdef LTM3 +#define LTM_LAST +#endif +#include +#include +#else +#define LTM_LAST +#endif diff --git a/tommath_superclass.h b/tommath_superclass.h new file mode 100644 index 0000000..043b224 --- /dev/null +++ b/tommath_superclass.h @@ -0,0 +1,70 @@ +/* super class file for PK algos */ + +/* default ... include all MPI */ +#define LTM_ALL + +/* RSA only (does not support DH/DSA/ECC) */ +// #define SC_RSA_1 + +/* For reference.... On an Athlon64 optimizing for speed... + LTM's mpi.o with all functions [striped] is 142KiB in size. +*/ + +/* Works for RSA only, mpi.o is 68KiB */ +#ifdef SC_RSA_1 + #define BN_MP_SHRINK_C + #define BN_MP_LCM_C + #define BN_MP_PRIME_RANDOM_EX_C + #define BN_MP_INVMOD_C + #define BN_MP_GCD_C + #define BN_MP_MOD_C + #define BN_MP_MULMOD_C + #define BN_MP_ADDMOD_C + #define BN_MP_EXPTMOD_C + #define BN_MP_SET_INT_C + #define BN_MP_INIT_MULTI_C + #define BN_MP_CLEAR_MULTI_C + #define BN_MP_UNSIGNED_BIN_SIZE_C + #define BN_MP_TO_UNSIGNED_BIN_C + #define BN_MP_MOD_D_C + #define BN_MP_PRIME_RABIN_MILLER_TRIALS_C + #define BN_REVERSE_C + #define BN_PRIME_TAB_C + + /* other modifiers */ +// #define BN_MP_DIV_SMALL /* Slower division, not critical (currently buggy?) */ + + /* here we are on the last pass so we turn things off. The functions classes are still there + * but we remove them specifically from the build. This also invokes tweaks in functions + * like removing support for even moduli, etc... + */ +#ifdef LTM_LAST + #undef BN_MP_TOOM_MUL_C + #undef BN_MP_TOOM_SQR_C + #undef BN_MP_KARATSUBA_MUL_C + #undef BN_MP_KARATSUBA_SQR_C + #undef BN_MP_REDUCE_C + #undef BN_MP_REDUCE_SETUP_C + #undef BN_MP_DR_IS_MODULUS_C + #undef BN_MP_DR_SETUP_C + #undef BN_MP_DR_REDUCE_C + #undef BN_MP_REDUCE_IS_2K_C + #undef BN_MP_REDUCE_2K_SETUP_C + #undef BN_MP_REDUCE_2K_C + #undef BN_S_MP_EXPTMOD_C + #undef BN_MP_DIV_3_C + #undef BN_S_MP_MUL_HIGH_DIGS_C + #undef BN_FAST_S_MP_MUL_HIGH_DIGS_C + #undef BN_FAST_MP_INVMOD_C + + /* To safely undefine these you have to make sure your RSA key won't exceed the Comba threshold + * which is roughly 255 digits [7140 bits for 32-bit machines, 15300 bits for 64-bit machines] + * which means roughly speaking you can handle upto 2536-bit RSA keys with these defined without + * trouble. + */ + #undef BN_S_MP_MUL_DIGS_C + #undef BN_S_MP_SQR_C + #undef BN_MP_MONTGOMERY_REDUCE_C +#endif + +#endif diff --git a/whirl.c b/whirl.c index 5233c47..8135b93 100644 --- a/whirl.c +++ b/whirl.c @@ -50,9 +50,9 @@ const struct _hash_descriptor whirlpool_desc = SB7(GB(a, i-7, 0)) #ifdef CLEAN_STACK -static void _whirlpool_compress(hash_state *md, unsigned char *buf) +static int _whirlpool_compress(hash_state *md, unsigned char *buf) #else -static void whirlpool_compress(hash_state *md, unsigned char *buf) +static int whirlpool_compress(hash_state *md, unsigned char *buf) #endif { ulong64 K[2][8], T[3][8]; @@ -90,7 +90,7 @@ static void whirlpool_compress(hash_state *md, unsigned char *buf) /* xor the constant */ K[0][0] ^= cont[x+1]; - /* apply main transform to T[0] into T[1] */ + /* apply main transform to T[1] into T[0] */ for (y = 0; y < 8; y++) { T[0][y] = theta_pi_gamma(T[1], y) ^ K[0][y]; } @@ -100,22 +100,27 @@ static void whirlpool_compress(hash_state *md, unsigned char *buf) for (x = 0; x < 8; x++) { md->whirlpool.state[x] ^= T[0][x] ^ T[2][x]; } + + return CRYPT_OK; } #ifdef CLEAN_STACK -static void whirlpool_compress(hash_state *md, unsigned char *buf) +static int whirlpool_compress(hash_state *md, unsigned char *buf) { - _whirlpool_compress(md, buf); + int err; + err = _whirlpool_compress(md, buf); burn_stack((5 * 8 * sizeof(ulong64)) + (2 * sizeof(int))); + return err; } #endif -void whirlpool_init(hash_state * md) +int whirlpool_init(hash_state * md) { _ARGCHK(md != NULL); zeromem(&md->whirlpool, sizeof(md->whirlpool)); + return CRYPT_OK; } HASH_PROCESS(whirlpool_process, whirlpool_compress, whirlpool, 64) diff --git a/yarrow.c b/yarrow.c index 5b48bee..333892e 100644 --- a/yarrow.c +++ b/yarrow.c @@ -65,7 +65,7 @@ int yarrow_start(prng_state *prng) prng->yarrow.cipher = register_cipher(&safer_sk128_desc); #elif defined(DES) prng->yarrow.cipher = register_cipher(&des3_desc); -#elif +#else #error YARROW needs at least one CIPHER #endif if ((err = cipher_is_valid(prng->yarrow.cipher)) != CRYPT_OK) { @@ -118,7 +118,9 @@ int yarrow_add_entropy(const unsigned char *buf, unsigned long len, prng_state * } /* start the hash */ - hash_descriptor[prng->yarrow.hash].init(&md); + if ((err = hash_descriptor[prng->yarrow.hash].init(&md)) != CRYPT_OK) { + return err; + } /* hash the current pool */ if ((err = hash_descriptor[prng->yarrow.hash].process(&md, prng->yarrow.pool,