From 6ac9952498a6eac39e9811d4bc8fc4c3f97b2bdd Mon Sep 17 00:00:00 2001 From: Tom St Denis Date: Sun, 17 Apr 2005 11:37:13 +0000 Subject: [PATCH] added libtomcrypt-1.01 --- LICENSE | 4 - TODO | 1 + changes | 69 ++ crypt.tex | 894 +++++++++++++++++- demos/test.c | 19 + demos/test/.ccmalloc | 356 ------- demos/test/mac_test.c | 12 - demos/test/makefile | 25 - demos/test/makefile.icc | 14 - demos/test/makefile.msvc | 14 - demos/test/makefile.shared | 19 - demos/test/test.c | 271 ------ demos/test/test.h | 41 - demos/timing.c | 23 + demos/tv_gen.c | 123 +++ doc/crypt.pdf | Bin 401670 -> 456995 bytes genlist.sh | 4 +- makefile | 208 ++-- makefile.cygwin_dll | 117 --- makefile.icc | 172 ++-- makefile.msvc | 153 +-- makefile.shared | 185 ++-- notes/ccm_tv.txt | 214 +++++ notes/cipher_tv.txt | 216 +++++ notes/eax_tv.txt | 76 ++ notes/gcm_tv.txt | 214 +++++ notes/ocb_tv.txt | 76 ++ notes/omac_tv.txt | 76 ++ notes/pmac_tv.txt | 76 ++ parsenames.pl | 4 +- src/ciphers/aes/aes.c | 25 +- src/ciphers/aes/aes_tab.c | 2 +- src/ciphers/anubis.c | 83 +- src/ciphers/blowfish.c | 13 +- src/ciphers/cast5.c | 13 +- src/ciphers/des.c | 29 +- src/ciphers/khazad.c | 13 +- src/ciphers/noekeon.c | 13 +- src/ciphers/rc2.c | 13 +- src/ciphers/rc5.c | 13 +- src/ciphers/rc6.c | 13 +- src/ciphers/safer/safer.c | 27 +- src/ciphers/safer/safer_tab.c | 2 +- src/ciphers/safer/saferp.c | 13 +- src/ciphers/skipjack.c | 13 +- src/ciphers/twofish/twofish.c | 13 +- src/ciphers/twofish/twofish_tab.c | 2 +- src/ciphers/xtea.c | 13 +- src/encauth/ccm/ccm_memory.c | 306 ++++++ src/encauth/ccm/ccm_test.c | 170 ++++ src/encauth/eax/eax_addheader.c | 2 +- src/encauth/eax/eax_decrypt.c | 2 +- src/encauth/eax/eax_decrypt_verify_memory.c | 2 +- src/encauth/eax/eax_done.c | 7 +- src/encauth/eax/eax_encrypt.c | 2 +- .../eax/eax_encrypt_authenticate_memory.c | 2 +- src/encauth/eax/eax_init.c | 2 +- src/encauth/eax/eax_test.c | 2 +- src/encauth/gcm/gcm_add_aad.c | 120 +++ src/encauth/gcm/gcm_add_iv.c | 90 ++ src/encauth/gcm/gcm_done.c | 80 ++ src/encauth/gcm/gcm_gf_mult.c | 89 ++ src/encauth/gcm/gcm_init.c | 88 ++ src/encauth/gcm/gcm_memory.c | 89 ++ src/encauth/gcm/gcm_process.c | 147 +++ src/encauth/gcm/gcm_reset.c | 40 + src/encauth/gcm/gcm_test.c | 361 +++++++ src/encauth/ocb/ocb_decrypt.c | 2 +- src/encauth/ocb/ocb_decrypt_verify_memory.c | 2 +- src/encauth/ocb/ocb_done_decrypt.c | 2 +- src/encauth/ocb/ocb_done_encrypt.c | 2 +- src/encauth/ocb/ocb_encrypt.c | 2 +- .../ocb/ocb_encrypt_authenticate_memory.c | 2 +- src/encauth/ocb/ocb_init.c | 2 +- src/encauth/ocb/ocb_ntz.c | 2 +- src/encauth/ocb/ocb_shift_xor.c | 2 +- src/encauth/ocb/ocb_test.c | 2 +- src/encauth/ocb/s_ocb_done.c | 3 +- src/hashes/chc/chc.c | 2 +- src/hashes/helper/hash_file.c | 2 +- src/hashes/helper/hash_filehandle.c | 2 +- src/hashes/helper/hash_memory.c | 2 +- src/hashes/helper/hash_memory_multi.c | 2 +- src/hashes/md2.c | 2 +- src/hashes/md4.c | 2 +- src/hashes/md5.c | 2 +- src/hashes/rmd128.c | 2 +- src/hashes/rmd160.c | 2 +- src/hashes/sha1.c | 2 +- src/hashes/sha2/sha224.c | 2 +- src/hashes/sha2/sha256.c | 2 +- src/hashes/sha2/sha384.c | 2 +- src/hashes/sha2/sha512.c | 2 +- src/hashes/tiger.c | 2 +- src/hashes/whirl/whirl.c | 2 +- src/headers/ltc_tommath.h | 26 +- src/headers/tomcrypt.h | 5 +- src/headers/tomcrypt_cfg.h | 24 +- src/headers/tomcrypt_cipher.h | 130 ++- src/headers/tomcrypt_custom.h | 37 +- src/headers/tomcrypt_hash.h | 196 +--- src/headers/tomcrypt_mac.h | 297 ++++++ src/headers/tomcrypt_macros.h | 44 +- src/headers/tomcrypt_pk.h | 2 +- src/headers/tommath_class.h | 52 +- src/headers/tommath_superclass.h | 4 +- src/mac/hmac/hmac_done.c | 2 +- src/mac/hmac/hmac_file.c | 2 +- src/mac/hmac/hmac_init.c | 2 +- src/mac/hmac/hmac_memory.c | 2 +- src/mac/hmac/hmac_memory_multi.c | 2 +- src/mac/hmac/hmac_process.c | 2 +- src/mac/hmac/hmac_test.c | 2 +- src/mac/omac/omac_done.c | 3 +- src/mac/omac/omac_file.c | 2 +- src/mac/omac/omac_init.c | 8 +- src/mac/omac/omac_memory.c | 2 +- src/mac/omac/omac_memory_multi.c | 2 +- src/mac/omac/omac_process.c | 18 +- src/mac/omac/omac_test.c | 2 +- src/mac/pelican/pelican.c | 149 +++ src/mac/pelican/pelican_memory.c | 55 ++ src/mac/pelican/pelican_test.c | 116 +++ src/mac/pmac/pmac_done.c | 3 +- src/mac/pmac/pmac_file.c | 2 +- src/mac/pmac/pmac_init.c | 11 +- src/mac/pmac/pmac_memory.c | 2 +- src/mac/pmac/pmac_memory_multi.c | 6 +- src/mac/pmac/pmac_ntz.c | 2 +- src/mac/pmac/pmac_process.c | 29 +- src/mac/pmac/pmac_shift_xor.c | 9 +- src/mac/pmac/pmac_test.c | 2 +- src/misc/base64/base64_decode.c | 16 +- src/misc/base64/base64_encode.c | 2 +- src/misc/burn_stack.c | 2 +- src/misc/crypt/crypt.c | 27 +- src/misc/crypt/crypt_argchk.c | 2 +- src/misc/crypt/crypt_cipher_descriptor.c | 6 +- src/misc/crypt/crypt_cipher_is_valid.c | 2 +- src/misc/crypt/crypt_find_cipher.c | 2 +- src/misc/crypt/crypt_find_cipher_any.c | 2 +- src/misc/crypt/crypt_find_cipher_id.c | 2 +- src/misc/crypt/crypt_find_hash.c | 2 +- src/misc/crypt/crypt_find_hash_any.c | 2 +- src/misc/crypt/crypt_find_hash_id.c | 2 +- src/misc/crypt/crypt_find_prng.c | 2 +- src/misc/crypt/crypt_hash_descriptor.c | 9 +- src/misc/crypt/crypt_hash_is_valid.c | 2 +- src/misc/crypt/crypt_prng_descriptor.c | 6 +- src/misc/crypt/crypt_prng_is_valid.c | 2 +- src/misc/crypt/crypt_register_cipher.c | 2 +- src/misc/crypt/crypt_register_hash.c | 2 +- src/misc/crypt/crypt_register_prng.c | 4 +- src/misc/crypt/crypt_unregister_cipher.c | 2 +- src/misc/crypt/crypt_unregister_hash.c | 2 +- src/misc/crypt/crypt_unregister_prng.c | 2 +- src/misc/error_to_string.c | 2 +- src/misc/mpi/is_prime.c | 2 +- src/misc/mpi/mpi.c | 683 ++++++++----- src/misc/mpi/mpi_to_ltc_error.c | 2 +- src/misc/mpi/rand_prime.c | 3 +- src/misc/pkcs5/pkcs_5_1.c | 4 +- src/misc/pkcs5/pkcs_5_2.c | 5 +- src/misc/zeromem.c | 11 +- src/modes/cbc/cbc_decrypt.c | 86 +- src/modes/cbc/cbc_done.c | 38 + src/modes/cbc/cbc_encrypt.c | 59 +- src/modes/cbc/cbc_getiv.c | 2 +- src/modes/cbc/cbc_setiv.c | 2 +- src/modes/cbc/cbc_start.c | 2 +- src/modes/cfb/cfb_decrypt.c | 2 +- src/modes/cfb/cfb_done.c | 38 + src/modes/cfb/cfb_encrypt.c | 2 +- src/modes/cfb/cfb_getiv.c | 2 +- src/modes/cfb/cfb_setiv.c | 2 +- src/modes/cfb/cfb_start.c | 2 +- src/modes/ctr/ctr_decrypt.c | 2 +- src/modes/ctr/ctr_done.c | 38 + src/modes/ctr/ctr_encrypt.c | 32 +- src/modes/ctr/ctr_getiv.c | 2 +- src/modes/ctr/ctr_setiv.c | 2 +- src/modes/ctr/ctr_start.c | 2 +- src/modes/ecb/ecb_decrypt.c | 39 +- src/modes/ecb/ecb_done.c | 38 + src/modes/ecb/ecb_encrypt.c | 22 +- src/modes/ecb/ecb_start.c | 2 +- src/modes/ofb/ofb_decrypt.c | 2 +- src/modes/ofb/ofb_done.c | 38 + src/modes/ofb/ofb_encrypt.c | 2 +- src/modes/ofb/ofb_getiv.c | 2 +- src/modes/ofb/ofb_setiv.c | 2 +- src/modes/ofb/ofb_start.c | 2 +- src/pk/asn1/der/der_decode_integer.c | 2 +- src/pk/asn1/der/der_encode_integer.c | 2 +- src/pk/asn1/der/der_get_multi_integer.c | 2 +- src/pk/asn1/der/der_length_integer.c | 2 +- src/pk/asn1/der/der_put_multi_integer.c | 2 +- src/pk/dh/dh.c | 2 +- src/pk/dh/dh_sys.c | 2 +- src/pk/dsa/dsa_export.c | 2 +- src/pk/dsa/dsa_free.c | 2 +- src/pk/dsa/dsa_import.c | 2 +- src/pk/dsa/dsa_make_key.c | 2 +- src/pk/dsa/dsa_sign_hash.c | 2 +- src/pk/dsa/dsa_verify_hash.c | 2 +- src/pk/dsa/dsa_verify_key.c | 2 +- src/pk/ecc/ecc.c | 341 +++++-- src/pk/ecc/ecc_sys.c | 6 +- src/pk/packet_store_header.c | 2 +- src/pk/packet_valid_header.c | 2 +- src/pk/pkcs1/pkcs_1_i2osp.c | 2 +- src/pk/pkcs1/pkcs_1_mgf1.c | 5 +- src/pk/pkcs1/pkcs_1_oaep_decode.c | 14 +- src/pk/pkcs1/pkcs_1_oaep_encode.c | 13 +- src/pk/pkcs1/pkcs_1_os2ip.c | 2 +- src/pk/pkcs1/pkcs_1_pss_decode.c | 15 +- src/pk/pkcs1/pkcs_1_pss_encode.c | 13 +- src/pk/pkcs1/pkcs_1_v15_es_decode.c | 2 +- src/pk/pkcs1/pkcs_1_v15_es_encode.c | 2 +- src/pk/pkcs1/pkcs_1_v15_sa_decode.c | 2 +- src/pk/pkcs1/pkcs_1_v15_sa_encode.c | 2 +- src/pk/rsa/rsa_decrypt_key.c | 2 +- src/pk/rsa/rsa_encrypt_key.c | 2 +- src/pk/rsa/rsa_export.c | 43 +- src/pk/rsa/rsa_exptmod.c | 2 +- src/pk/rsa/rsa_free.c | 2 +- src/pk/rsa/rsa_import.c | 33 +- src/pk/rsa/rsa_make_key.c | 2 +- src/pk/rsa/rsa_sign_hash.c | 2 +- src/pk/rsa/rsa_v15_decrypt_key.c | 2 +- src/pk/rsa/rsa_v15_encrypt_key.c | 2 +- src/pk/rsa/rsa_v15_sign_hash.c | 2 +- src/pk/rsa/rsa_v15_verify_hash.c | 2 +- src/pk/rsa/rsa_verify_hash.c | 2 +- src/prngs/fortuna.c | 2 +- src/prngs/rc4.c | 2 +- src/prngs/rng_get_bytes.c | 2 +- src/prngs/rng_make_prng.c | 2 +- src/prngs/sober128.c | 2 +- src/prngs/sprng.c | 2 +- src/prngs/yarrow.c | 6 +- {demos/test => testprof}/base64_test.c | 4 +- {demos/test => testprof}/cipher_hash_test.c | 2 +- {demos/test => testprof}/der_tests.c | 4 +- {demos/test => testprof}/dh_tests.c | 12 +- {demos/test => testprof}/dsa_test.c | 6 +- {demos/test => testprof}/ecc_test.c | 14 +- testprof/mac_test.c | 31 + testprof/makefile | 15 + testprof/makefile.icc | 15 + testprof/makefile.msvc | 10 + testprof/makefile.shared | 15 + {demos/test => testprof}/modes_test.c | 36 +- {demos/test => testprof}/pkcs_1_test.c | 8 +- {demos/test => testprof}/rsa_test.c | 56 +- {demos/test => testprof}/store_test.c | 4 +- testprof/test.c | 9 + testprof/tomcrypt_test.h | 73 ++ {demos => testprof}/x86_prof.c | 427 +++++++-- 259 files changed, 7203 insertions(+), 2286 deletions(-) create mode 100644 TODO create mode 100644 demos/test.c delete mode 100644 demos/test/.ccmalloc delete mode 100644 demos/test/mac_test.c delete mode 100644 demos/test/makefile delete mode 100644 demos/test/makefile.icc delete mode 100644 demos/test/makefile.msvc delete mode 100644 demos/test/makefile.shared delete mode 100644 demos/test/test.c delete mode 100644 demos/test/test.h create mode 100644 demos/timing.c delete mode 100644 makefile.cygwin_dll create mode 100644 notes/ccm_tv.txt create mode 100644 notes/gcm_tv.txt create mode 100644 src/encauth/ccm/ccm_memory.c create mode 100644 src/encauth/ccm/ccm_test.c create mode 100644 src/encauth/gcm/gcm_add_aad.c create mode 100644 src/encauth/gcm/gcm_add_iv.c create mode 100644 src/encauth/gcm/gcm_done.c create mode 100644 src/encauth/gcm/gcm_gf_mult.c create mode 100644 src/encauth/gcm/gcm_init.c create mode 100644 src/encauth/gcm/gcm_memory.c create mode 100644 src/encauth/gcm/gcm_process.c create mode 100644 src/encauth/gcm/gcm_reset.c create mode 100644 src/encauth/gcm/gcm_test.c create mode 100644 src/headers/tomcrypt_mac.h create mode 100644 src/mac/pelican/pelican.c create mode 100644 src/mac/pelican/pelican_memory.c create mode 100644 src/mac/pelican/pelican_test.c create mode 100644 src/modes/cbc/cbc_done.c create mode 100644 src/modes/cfb/cfb_done.c create mode 100644 src/modes/ctr/ctr_done.c create mode 100644 src/modes/ecb/ecb_done.c create mode 100644 src/modes/ofb/ofb_done.c rename {demos/test => testprof}/base64_test.c (86%) rename {demos/test => testprof}/cipher_hash_test.c (97%) rename {demos/test => testprof}/der_tests.c (96%) rename {demos/test => testprof}/dh_tests.c (84%) rename {demos/test => testprof}/dsa_test.c (90%) rename {demos/test => testprof}/ecc_test.c (84%) create mode 100644 testprof/mac_test.c create mode 100644 testprof/makefile create mode 100644 testprof/makefile.icc create mode 100644 testprof/makefile.msvc create mode 100644 testprof/makefile.shared rename {demos/test => testprof}/modes_test.c (84%) rename {demos/test => testprof}/pkcs_1_test.c (94%) rename {demos/test => testprof}/rsa_test.c (81%) rename {demos/test => testprof}/store_test.c (95%) create mode 100644 testprof/test.c create mode 100644 testprof/tomcrypt_test.h rename {demos => testprof}/x86_prof.c (61%) diff --git a/LICENSE b/LICENSE index 50e7435..5d678c5 100644 --- a/LICENSE +++ b/LICENSE @@ -1,9 +1,5 @@ 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. - Tom St Denis diff --git a/TODO b/TODO new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/TODO @@ -0,0 +1 @@ + diff --git a/changes b/changes index 6b4bc25..bdc2c06 100644 --- a/changes +++ b/changes @@ -1,3 +1,72 @@ +April 17th, 2005 +v1.01 + ** Secure Science Corporation has supported this release cycle by sponsoring the development time taken. Their + continuing support of this project has helped me maintain a steady pace in order to keep LibTomCrypt up to date, + stable and more efficient. + ----------------------------------------------------------------------------------------------------- + -- Updated base64_decode.c so if there are more than 3 '=' signs it would stop parsing + -- Merged in latest mpi that fixed a few bugs here and there + -- Updated OAEP encoder/decoder to catch when the hash output is too large + Cleaned up PSS code too + -- Andy Bontoft fixed a bug in my demos/tests/makefile.msvc ... seems "dsa_test.c" isn't an object + afterall. Thanks. + -- Made invalid ECC key sizes (configuration) not hard fault the program (it returns an error code now) + -- SAFER has been re-enabled after I was pointed to http://www.ciphersbyritter.com/NEWS2/95032301.HTM + [Mark Kotiaho] + -- Added CCM mode to the encauth list (now has EAX, OCB and CCM, c'est un treo magnifique!) + -- Added missing ASN.1 header to the RSA keys ... oops... now the rsa_export/import are FULLY compatible + with other libs like OpenSSL (comment: Test vectors would go a long way RSA...) + -- Manually merged in fix to the prime_random_ex() LTM function that ensures the 2nd MSB is set properly. Now + When you say "I want a 1024/8 byte RSA key" the MSB bit of the modulus is set as expected. Note I generally + don't view this as a "huge issue" but it's just one less nit to worry about. [Bryan Klisch] + -- A new CVS has been setup on my Athlon64 box... if you want developer access send me an email (and at this point the email would have to be awesome). + -- Updated API for ECB and CBC shell code. Now can process N whole blocks in one call (like $DEITY intended) + -- Introduced a new "hardware accel" framework that can be used to speed up cipher ECB, CBC and CTR mode + calls. Later on dependent code (e.g. OMAC, CCM) will be re-written to use the generic cbc/ctr functions. But now + if you [say] call ctr_encrypt() with a cipher descriptor that has hardware CTR it will automatically + be used (e.g. no code rewrites) + -- Now ships with 20% more love. + -- x86_prof now uses ECB shell code (hint: accelerators) and outputs cycles per BLOCK not byte. This will make it a bit + easier to compare hardware vs. software cipher implementations. It also emits timings for CBC and CTR modes + -- [Peter LaDow] fixed a typo w.r.t. XREALLOC macro (spelling counts kids!) + -- Fixed bug with __x86_64__ where ROL64/ROR64 with LTC_NO_ROLC would be the 32-bit versions instead... + -- Shipping with preliminary GCM code (disabled). It's buggy (stack overflow hidden somewhere). If anyone can spot it let me know. + -- Added Pelican MAC [it's an AES based fast MAC] to the list of supported MACs + -- Added LTC_FAST [and you can disable by defining LTC_NO_FAST] so that CBC and CTR mode XOR whole words [e.g. 32 or 64 bits] at a time + instead of one byte. On my AMD64 this reduced the overhead for AES-128-CBC from 4.56 cycles/byte to around 1 cycle/byte. This requires + that you either allow unaligned read/writes [e.g. x86_32/x86_64] or align all your data. It won't go out of it's way to ensure + aligned access. Only enabled for x86_* platforms by default since they allow unaligned read/writes. + -- Added LTC_FAST support to PMAC (drops the cycle/byte by about 9 cycles on my AMD64) [note: I later rewrote this prior to release] + -- Updated "profiled" target to work with the new directory layout + -- Added [demo only] optimized RC5-CTR code to x86_prof demo to show off how to make an accelerator + [This has been removed prior to release... It may re-appear later] + -- Added CCM acelerator callbacks to the list [now supports ECB, CTR, CBC and now CCM]. + -- Added chapter to manual about accelerators (you know you want it) + -- Added "bswap" optimizations to x86 LOAD/STORE with big endian. Can be disabled by defining LTC_NO_BSWAP + -- LTC_NO_ASM is now the official "disable all non-portable stuff" macro. When defined it will make the code endian-neutral, + disable any form of ASM and disable LTC_FAST load/stores. Essentially build the library with this defined if you're having + trouble building the library (old GCCs for instance dislike the ROLc macro) + -- Added tomcrypt_mac.h and moved MAC/encMAC functions from tomcrypt_hash.h into it + -- Added "done" function to ciphers and the five chaining modes [and things like omac/pmac/etc] + -- Changed install group to "wheel" from "root". + -- Replaced // comments with /**/ so it will build on older UNIX-like platforms + -- x86_prof builds and runs with IntelCC fine now + -- Added "stest" build to intel CC to test static linked from within the dir (so you don't have to install to test) + -- Moved testing/benchmark into testprof directory and build it as part of the build. Now you can link against libtomcrypt_prof.a to get + testing info (hint: hardware developers ;-) ) + -- Added CCM to tv_gen + -- Added demos to MSVC makefile + -- Removed -funroll-all-loops from GCC makefile and replaced with -funroll-loops which is a bit more sane (P4 ain't got much cache for the IDATA) + -- Fixed GCM prior to release and re-enabled it. It has not been optimized but it does conform when compiled with optimizations. + -- I've since optimized GCM and CCM. They're close in speed but GCM is more flexible imho (though EAX is more flexible than both) + -- For kicks I optimized the ECC code to use projective points. Gets between 3.21x (Prescott P4) to 4.53x (AMD64) times faster than before at 160-bit keys and the + speedup grows as the keysize grows. Basically removing most practical reasons to "not use the ECC code". Enjoy. + -- Added LTC_FAST support to OMAC/PMAC and doubled it's speed on my amd64 [faster on the P4 too I guess] + -- Added GCM to tv_gen + -- Removed "makefile.cygwin_dll" as it's not really used by anyone and not worth the effort (hell I hardly maintain the MSVC makefiles ...) + -- Updated a few files in the "misc" directory to have correct @file comments for doxygen + -- Removed "profile" target since it was slower anyways (go figure...) + December 31st, 2004 v1.00 -- Added "r,s == 0" check to dsa_verify_hash() diff --git a/crypt.tex b/crypt.tex index 4cfd4c9..fd8f2e7 100644 --- a/crypt.tex +++ b/crypt.tex @@ -47,10 +47,10 @@ \def\gap{\vspace{0.5ex}} \makeindex \begin{document} -\title{LibTomCrypt \\ Version 1.00} +\title{LibTomCrypt \\ Version 1.01} \author{Tom St Denis \\ \\ -tomstdenis@iahu.ca \\ +tomstdenis@gmail.com \\ http://libtomcrypt.org } \maketitle @@ -154,14 +154,12 @@ under a public domain license: \begin{enumerate} \item rc2.c - \item safer.c \end{enumerate} `mpi.c'' was originally written by Michael Fromberger (sting@linguist.dartmouth.edu) but has since been replaced with my LibTomMath library which is public domain. -``rc2.c'' is based on publicly available code that is not attributed to a person from the given source. ``safer.c'' -was written by Richard De Moliner (demoliner@isi.ee.ethz.ch) and seems to be free for use. +``rc2.c'' is based on publicly available code that is not attributed to a person from the given source. The project is hereby released as public domain. @@ -246,8 +244,7 @@ The header file ``tomcrypt.h'' also includes ``stdio.h'', ``string.h'', ``stdlib There are a few helper macros to make the coding process a bit easier. The first set are related to loading and storing 32/64-bit words in little/big endian format. The macros are: -\index{STORE32L} \index{STORE64L} \index{LOAD32L} \index{LOAD64L} -\index{STORE32H} \index{STORE64H} \index{LOAD32H} \index{LOAD64H} \index{BSWAP} +\index{STORE32L} \index{STORE64L} \index{LOAD32L} \index{LOAD64L} \index{STORE32H} \index{STORE64H} \index{LOAD32H} \index{LOAD64H} \index{BSWAP} \begin{small} \begin{center} \begin{tabular}{|c|c|c|} @@ -259,14 +256,14 @@ There are a few helper macros to make the coding process a bit easier. The firs \hline STORE64H(x, y) & {\bf unsigned long long} x, {\bf unsigned char} *y & $x \to y[7 \ldots 0]$ \\ \hline LOAD32H(x, y) & {\bf unsigned long} x, {\bf unsigned char} *y & $y[3 \ldots 0] \to x$ \\ \hline LOAD64H(x, y) & {\bf unsigned long long} x, {\bf unsigned char} *y & $y[7 \ldots 0] \to x$ \\ - \hline BSWAP(x) & {\bf unsigned long} x & Swaps the byte order of x. \\ + \hline BSWAP(x) & {\bf unsigned long} x & Swaps byte order (32--bits only) \\ \hline \end{tabular} \end{center} \end{small} There are 32 and 64-bit cyclic rotations as well: -\index{ROL} \index{ROR} +\index{ROL} \index{ROR} \index{ROL64} \index{ROR64} \index{ROLc} \index{RORc} \index{ROL64c} \index{ROR64c} \begin{center} \begin{tabular}{|c|c|c|} \hline ROL(x, y) & {\bf unsigned long} x, {\bf unsigned long} y & $x << y, 0 \le y \le 31$ \\ @@ -295,7 +292,7 @@ int main(void) { unsigned long x; int err; - /* ... Make up the RSA key somehow */ + /* ... Make up the RSA key somehow ... */ /* lets export the key, set x to the size of the output buffer */ x = sizeof(buffer); @@ -343,6 +340,7 @@ should never use the ECB modes directly to encrypt data. Instead you should use or use one of the provided chaining modes. All of the ciphers are written as ECB interfaces since it allows the rest of the API to grow in a modular fashion. +\subsection{Key Scheduling} All ciphers store their scheduled keys in a single data type called ``symmetric\_key''. This allows all ciphers to have the same prototype and store their keys as naturally as possible. This also removes the need for dynamic memory allocation and allows you to allocate a fixed sized buffer for storing scheduled keys. All ciphers provide five visible @@ -361,6 +359,7 @@ that you should only used this scheduled key with the intended cipher. For exam pass the scheduled key onto ``rc5\_ecb\_encrypt()''. All setup functions do not allocate memory off the heap so when you are done with a key you can simply discard it (e.g. they can be on the stack). +\subsection{ECB Encryption and Decryption} To encrypt or decrypt a block in ECB mode there are these two function classes \index{Cipher Encrypt} \index{Cipher Decrypt} \begin{verbatim} @@ -376,12 +375,16 @@ the same buffer. For the encrypt function ``pt''\footnote{pt stands for plainte ``ct''\footnote{ct stands for ciphertext.} is the output. For the decryption function it's the opposite. To test a particular cipher against test vectors\footnote{As published in their design papers.} call the self-test function +\subsection{Self--Testing} \index{Cipher Testing} \begin{verbatim} int XXX_test(void); \end{verbatim} This function will return {\bf CRYPT\_OK} if the cipher matches the test vectors from the design publication it is -based upon. Finally for each cipher there is a function which will help find a desired key size: +based upon. + +\subsection{Key Sizing} +For each cipher there is a function which will help find a desired key size: \begin{verbatim} int XXX_keysize(int *keysize); \end{verbatim} @@ -407,6 +410,15 @@ int main(void) \end{small} This should indicate a keysize of sixteen bytes is suggested. +\subsection{Cipher Termination} +When you are finished with a cipher you can de--initialize it with the done function. +\begin{verbatim} +void XXX_done(symmetric_key *skey); +\end{verbatim} +For the software based ciphers within LibTomCrypt this function will not do anything. However, user supplied +cipher descriptors may require calls to it for resource management. To be compliant all functions which call a cipher +setup function must also call the respective cipher done function when finished. + \subsection{Simple Encryption Demonstration} An example snippet that encodes a block with Blowfish in ECB mode is below. @@ -445,6 +457,10 @@ int main(void) &skey); /* our previously scheduled key */ /* now we have decrypted ct to the original plaintext in pt */ + + /* Terminate the cipher context */ + blowfish_done(&skey); + return 0; } \end{verbatim} @@ -470,6 +486,7 @@ size. To facilitate automatic routines an array of cipher descriptors is provided in the array ``cipher\_descriptor''. An element of this array has the following format: +\begin{small} \begin{verbatim} struct _cipher_descriptor { char *name; @@ -478,16 +495,43 @@ struct _cipher_descriptor { max_key_length, block_length, default_rounds; - int (*setup)(const unsigned char *key, int keylen, int num_rounds, - symmetric_key *skey); - void (*ecb_encrypt)(const unsigned char *pt, unsigned char *ct, - symmetric_key *skey); - void (*ecb_decrypt)(const unsigned char *ct, unsigned char *pt, - symmetric_key *skey); + int (*setup)(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); + void (*ecb_encrypt)(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); + void (*ecb_decrypt)(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); int (*test)(void); + void (*done)(symmetric_key *skey); int (*keysize)(int *keysize); + + void (*accel_ecb_encrypt)(const unsigned char *pt, + unsigned char *ct, + unsigned long blocks, symmetric_key *skey); + void (*accel_ecb_decrypt)(const unsigned char *ct, + unsigned char *pt, + unsigned long blocks, symmetric_key *skey); + void (*accel_cbc_encrypt)(const unsigned char *pt, + unsigned char *ct, + unsigned long blocks, unsigned char *IV, + symmetric_key *skey); + void (*accel_cbc_decrypt)(const unsigned char *ct, + unsigned char *pt, + unsigned long blocks, unsigned char *IV, + symmetric_key *skey); + void (*accel_ctr_encrypt)(const unsigned char *pt, + unsigned char *ct, + unsigned long blocks, unsigned char *IV, + int mode, symmetric_key *skey); + void (*accel_ccm_memory)( + const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *header, unsigned long headerlen, + unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, unsigned long *taglen, + int direction); + }; \end{verbatim} +\end{small} Where ``name'' is the lower case ASCII version of the name. The fields ``min\_key\_length'' and ``max\_key\_length'' are the minimum and maximum key sizes in bytes. The ``block\_length'' member is the block size of the cipher @@ -722,7 +766,7 @@ block of memory with either of the three modes. The ECB and CBC modes process blocks of the same size as the cipher at a time. Therefore they are less flexible than the other modes. -\subsection{Implementation} +\subsection{Initialization} \index{CBC Mode} \index{CTR Mode} \index{OFB Mode} \index{CFB Mode} The library provides simple support routines for handling CBC, CTR, CFB, OFB and ECB encoded messages. Assuming the mode @@ -745,30 +789,32 @@ of the cipher you choose. It is important that the IV be random for each uniqu parameters ``key'', ``keylen'' and ``num\_rounds'' are the same as in the XXX\_setup() function call. The final parameter is a pointer to the structure you want to hold the information for the mode of operation. -Both routines return {\bf CRYPT\_OK} if the cipher initialized correctly, otherwise they return an error code. To -actually encrypt or decrypt the following routines are provided: +Both routines return {\bf CRYPT\_OK} if the cipher initialized correctly, otherwise they return an error code. + +\subsection{Encryption and Decryption} +To actually encrypt or decrypt the following routines are provided: \index{ecb\_encrypt()} \index{ecb\_decrypt()} \index{cfb\_encrypt()} \index{cfb\_decrypt()} \index{cbc\_encrypt()} \index{cbc\_decrypt()} \index{ofb\_encrypt()} \index{ofb\_decrypt()} \index{ctr\_encrypt()} \index{ctr\_decrypt()} \begin{verbatim} int XXX_encrypt(const unsigned char *pt, unsigned char *ct, - symmetric_XXX *XXX); -int XXX_decrypt(const unsigned char *ct, unsigned char *pt, - symmetric_XXX *XXX); - -int YYY_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_YYY *YYY); -int YYY_decrypt(const unsigned char *ct, unsigned char *pt, +int XXX_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_YYY *YYY); \end{verbatim} -Where ``XXX'' is one of (ecb, cbc) and ``YYY'' is one of (ctr, ofb, cfb). In the CTR, OFB and CFB cases ``len'' is the -size of the buffer (as number of chars) to encrypt or decrypt. The CTR, OFB and CFB modes are order sensitive but not +Where ``XXX'' is one of $\lbrace ecb, cbc, ctr, cfb, ofb \rbrace$. + +In all cases ``len'' is the size of the buffer (as number of octets) to encrypt or decrypt. The CTR, OFB and CFB modes are order sensitive but not chunk sensitive. That is you can encrypt ``ABCDEF'' in three calls like ``AB'', ``CD'', ``EF'' or two like ``ABCDE'' and ``F'' and end up with the same ciphertext. However, encrypting ``ABC'' and ``DABC'' will result in different ciphertexts. All five of the modes will return {\bf CRYPT\_OK} on success from the encrypt or decrypt functions. +In the ECB and CBC cases ``len'' must be a multiple of the ciphers block size. In the CBC case you must manually pad the end of your message (either with +zeroes or with whatever your protocol requires). + To decrypt in either mode you simply perform the setup like before (recall you have to fetch the IV value you used) and use the decrypt routine on all of the blocks. +\subsection{IV Manipulation} To change or read the IV of a previously initialized chaining mode use the following two functions. \index{cbc\_setiv()} \index{cbc\_getiv()} \index{ofb\_setiv()} \index{ofb\_getiv()} \index{cfb\_setiv()} \index{cfb\_getiv()} @@ -778,11 +824,23 @@ int XXX_getiv(unsigned char *IV, unsigned long *len, symmetric_XXX *XXX); int XXX_setiv(const unsigned char *IV, unsigned long len, symmetric_XXX *XXX); \end{verbatim} -The XXX\_getiv function will read the IV out of the chaining mode and store it into ``IV'' along with the length of the IV +The XXX\_getiv() functions will read the IV out of the chaining mode and store it into ``IV'' along with the length of the IV stored in ``len''. The XXX\_setiv will initialize the chaining mode state as if the original IV were the new IV specified. The length of the IV passed in must be the size of the ciphers block size. -The XXX\_setiv functions are handy if you wish to change the IV without re--keying the cipher. +The XXX\_setiv() functions are handy if you wish to change the IV without re--keying the cipher. + +\subsection{Stream Termination} +To terminate an open stream call the done function. + +\index{ecb\_done()} \index{cbc\_done()}\index{cfb\_done()}\index{ofb\_done()} \index{ctr\_done()} +\begin{verbatim} +int XXX_done(symmetric_XXX *XXX); +\end{verbatim} + +This will terminate the stream (by terminating the cipher) and return \textbf{CRYPT\_OK} if successful. + +\subsection{Examples} \newpage \begin{small} @@ -845,6 +903,12 @@ int main(void) return -1; } + /* terminate the stream */ + if ((err = ctr_done(&ctr)) != CRYPT_OK) { + printf("ctr_done error: %s\n", error_to_string(err)); + return -1; + } + /* clear up and return */ zeromem(key, sizeof(key)); zeromem(&ctr, sizeof(ctr)); @@ -1050,6 +1114,8 @@ They assume that ``pt'' and ``ct'' are the same size as the block cipher's block both functions given a single ``ocb'' state. For bi-directional communication you will have to initialize two ``ocb'' states (with different nonces). Also ``pt'' and ``ct'' may point to the same location in memory. +\subsubsection{State Termination} + When you are finished encrypting the message you call the following function to compute the tag. \index{ocb\_done\_encrypt()} @@ -1083,6 +1149,7 @@ tag of the message (internally) and then compare it against the ``taglen'' bytes ``res'' is set to zero. If all ``taglen'' bytes of ``tag'' can be verified then ``res'' is set to one (authenticated message). +\subsubsection{Packet Functions} To make life simpler the following two functions are provided for memory bound OCB. \index{ocb\_encrypt\_authenticate\_memory()} @@ -1112,6 +1179,238 @@ int ocb_decrypt_verify_memory(int cipher, Similarly this will OCB decrypt and compare the internally computed tag against the tag provided. ``res'' is set appropriately. +\subsection{CCM Mode} +CCM is a NIST proposal for Encrypt+Authenticate that is centered around using AES (or any 16--byte cipher) as a primitive. Unlike EAX and OCB mode +it is only meant for ``packet'' mode where the length of the input is known in advance. Since it is a packet mode function CCM only has one +function that performs the protocol. + +\index{ccm\_memory()} +\begin{verbatim} +int ccm_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *header, unsigned long headerlen, + unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, unsigned long *taglen, + int direction); +\end{verbatim} + +This performs the ``CCM'' operation on the data. The ``cipher'' variable indicates which cipher in the descriptor table to use. It must have a +16--byte block size for CCM. The key is ``key'' with a length of ``keylen'' octets. The nonce or salt is ``nonce'' of +length ``noncelen'' octets. The header is meta--data you want to send with the message but not have encrypted, it is stored in ``header'' +of length ``headerlen'' octets. The header can be zero octets long (if $headerlen = 0$ then you can pass ``header'' as \textbf{NULL}). + +The plaintext is stored in ``pt'' and the ciphertext in ``ct''. The length of both are expected to be equal and is passed in as ``ptlen''. It is +allowable that $pt = ct$. The ``direction'' variable indicates whether encryption (direction $=$ \textbf{CCM\_ENCRYPT}) or +decryption (direction $=$ \textbf{CCM\_DECRYPT}) is to be performed. + +As implemented this copy of CCM cannot handle a header or plaintext longer than $2^{32} - 1$ octets long. + +You can test the implementation of CCM with the following function. + +\index{ccm\_test()} +\begin{verbatim} +int ccm_test(void); +\end{verbatim} + +This will return \textbf{CRYPT\_OK} if the CCM routine passes known test vectors. + +\subsection{GCM Mode} +Galois counter mode is an IEEE proposal for authenticated encryption. Like EAX and OCB it can be used in a streaming capacity however, unlike EAX it cannot +accept ``additional authentication data'' (meta--data) after plaintext has been processed. This mode also only works with block ciphers with a sixteen +byte block. + +A GCM stream is meant to be processed in three modes each one sequential serial. First the initial vector (per session) data is processed. This should be +unique to every session. Next the the optional additional authentication data is processed and finally the plaintext. + +\subsubsection{Initialization} +To initialize the GCM context with a secret key call the following function. + +\index{gcm\_init()} +\begin{verbatim} +int gcm_init(gcm_state *gcm, int cipher, + const unsigned char *key, int keylen); +\end{verbatim} +This initializes the GCM state ``gcm'' for the given cipher indexed by ``cipher'' with a secret key ``key'' of length ``keylen'' octets. The cipher chosen +must have a 16--byte block size (e.g. AES). + +\subsubsection{Initial Vector} +After the state has been initialized (or reset) the next step is to add the session (or packet) initial vector. It should be unique per packet encrypted. + +\index{gcm\_add\_iv()} +\begin{verbatim} +int gcm_add_iv(gcm_state *gcm, + const unsigned char *IV, unsigned long IVlen); +\end{verbatim} + +This adds the initial vector octets from ``IV'' of length ``IVlen'' to the GCM state ``gcm''. You can call this function as many times as required +to process the entire IV. + +Note that the GCM protocols provides a ``shortcut'' for 12--byte IVs where no preprocessing is to be done. If you want to minimize per packet latency it's ideal +to only use 12--byte IVs. You can just increment it like a counter for each packet and the CTR [privacy] will be ensured. + +\subsubsection{Additional Authentication Data} +After the entire IV has been processed the additional authentication data can be processed. Unlike the IV a packet/session does not require additional +authentication data (AAD) for security. The AAD is meant to be used as side--channel data you want to be authenticated with the packet. Note that once +you begin adding AAD to the GCM state you cannot return to adding IV data until the state is reset. + +\index{gcm\_add\_aad()} +\begin{verbatim} +int gcm_add_aad(gcm_state *gcm, + const unsigned char *adata, unsigned long adatalen); +\end{verbatim} +This adds the additional authentication data ``adata'' of length ``adatalen'' to the GCM state ``gcm''. + +\subsubsection{Plaintext Processing} +After the AAD has been processed the plaintext (or ciphertext depending on the direction) can be processed. + +\index{gcm\_process()} +\begin{verbatim} +int gcm_process(gcm_state *gcm, + unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + int direction); +\end{verbatim} +This processes message data where ``pt'' is the plaintext and ``ct'' is the ciphertext. The length of both are equal and stored in ``ptlen''. Depending on the +mode ``pt'' is the input and ``ct'' is the output (or vice versa). When ``direction'' equals \textbf{GCM\_ENCRYPT} the plaintext is read, encrypted and stored +in the ciphertext buffer. When ``direction'' equals \textbf{GCM\_DECRYPT} the opposite occurs. + +\subsubsection{State Termination} +To terminate a GCM state and retrieve the message authentication tag call the following function. + +\index{gcm\_done()} +\begin{verbatim} +int gcm_done(gcm_state *gcm, + unsigned char *tag, unsigned long *taglen); +\end{verbatim} +This terminates the GCM state ``gcm'' and stores the tag in ``tag'' of length ``taglen'' octets. + +\subsubsection{State Reset} +The call to gcm\_init() will perform considerable pre--computation (when \textbf{GCM\_TABLES} is defined) and if you're going to be dealing with a lot of packets +it is very costly to have to call it repeatedly. To aid in this endeavour the reset function has been provided. + +\index{gcm\_reset()} +\begin{verbatim} +int gcm_reset(gcm_state *gcm); +\end{verbatim} + +This will reset the GCM state ``gcm'' to the state that gcm\_init() left it. The user would then call gcm\_add\_iv(), gcm\_add\_aad(), etc. + +\subsubsection{One--Shot Packet} +To process a single packet under any given key the following helper function can be used. + +\index{gcm\_memory()} +\begin{verbatim} +int gcm_memory( int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *IV, unsigned long IVlen, + const unsigned char *adata, unsigned long adatalen, + unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, unsigned long *taglen, + int direction); +\end{verbatim} + +This will initialize the GCM state with the given key, IV and AAD value then proceed to encrypt or decrypt the message text and store the final +message tag. The definition of the variables is the same as it is for all the manual functions. + +If you are processing many packets under the same key you shouldn't use this function as it invokes the pre--computation with each call. + +\subsubsection{Example Usage} +The following is an example usage of how to use GCM over multiple packets with a shared secret key. + +\begin{small} +\begin{verbatim} +#include + +int send_packet(const unsigned char *pt, unsigned long ptlen, + const unsigned char *iv, unsigned long ivlen, + const unsigned char *aad, unsigned long aadlen, + gcm_state *gcm) +{ + int err; + unsigned long taglen; + unsigned char tag[16]; + + /* reset the state */ + if ((err = gcm_reset(gcm)) != CRYPT_OK) { + return err; + } + + /* Add the IV */ + if ((err = gcm_add_iv(gcm, iv, ivlen)) != CRYPT_OK) { + return err; + } + + /* Add the AAD (note: aad can be NULL if aadlen == 0) */ + if ((err = gcm_add_aad(gcm, aad, aadlen)) != CRYPT_OK) { + return err; + } + + /* process the plaintext */ + if ((err = gcm_add_process(gcm, pt, ptlen, pt, GCM_ENCRYPT)) != CRYPT_OK) { + return err; + } + + /* Finish up and get the MAC tag */ + taglen = sizeof(tag); + if ((err = gcm_done(gcm, tag, &taglen)) != CRYPT_OK) { + return err; + } + + /* depending on the protocol and how IV is generated you may have to send it too... */ + send(socket, iv, ivlen, 0); + + /* send the aad */ + send(socket, aad, aadlen, 0); + + /* send the ciphertext */ + send(socket, pt, ptlen, 0); + + /* send the tag */ + send(socket, tag, taglen, 0); + + return CRYPT_OK; +} + +int main(void) +{ + gcm_state gcm; + unsigned char key[16], IV[12], pt[PACKET_SIZE]; + int err, x; + unsigned long ptlen; + + /* somehow fill key/IV with random values */ + + /* register AES */ + register_cipher(&aes_desc); + + /* init the GCM state */ + if ((err = gcm_init(&gcm, find_cipher("aes"), key, 16)) != CRYPT_OK) { + whine_and_pout(err); + } + + /* handle us some packets */ + for (;;) { + ptlen = make_packet_we_want_to_send(pt); + + /* use IV as counter (12 byte counter) */ + for (x = 11; x >= 0; x--) { + if (++IV[x]) { + break; + } + } + + if ((err = send_packet(pt, ptlen, iv, 12, NULL, 0, &gcm)) != CRYPT_OK) { + whine_and_pout(err); + } + } + return EXIT_SUCCESS; +} +\end{verbatim} +\end{small} + \chapter{One-Way Cryptographic Hash Functions} \section{Core Functions} @@ -1709,11 +2008,81 @@ and the cipher specified by the ``cipher'''th entry in the cipher\_descriptor ta the same rules as omac\_done. To test if the PMAC code is working there is the following function: +\index{pmac\_test()} \begin{verbatim} int pmac_test(void); \end{verbatim} Which returns {\bf CRYPT\_OK} if the code passes otherwise it returns an error code. +\section{Pelican MAC} +Pelican MAC is a new (experimental) MAC by the AES team that uses four rounds of AES as a ``mixing function''. It achieves a very high +rate of processing and is potentially very secure. It requires AES to be enabled to function. You do not have to register\_cipher() AES first though +as it calls AES directly. + +\index{pelican\_init()} +\begin{verbatim} +int pelican_init(pelican_state *pelmac, const unsigned char *key, unsigned long keylen); +\end{verbatim} +This will initialize the Pelican state with the given AES key. Once this has been done you can begin processing data. + +\index{pelican\_process()} +\begin{verbatim} +int pelican_process(pelican_state *pelmac, const unsigned char *in, unsigned long inlen); +\end{verbatim} +This will process ``inlen'' bytes of ``in'' through the Pelican MAC. It's best that you pass in multiples of 16 bytes as it makes the +routine more efficient but you may pass in any length of text. You can call this function as many times as required to process +an entire message. + +\index{pelican\_done()} +\begin{verbatim} +int pelican_done(pelican_state *pelmac, unsigned char *out); +\end{verbatim} +This terminates a Pelican MAC and writes the 16--octet tag to ``out''. + +\subsection{Example} + +\begin{verbatim} +#include +int main(void) +{ + pelican_state pelstate; + unsigned char key[32], tag[16]; + int err; + + /* somehow initialize a key */ + + /* initialize pelican mac */ + if ((err = pelican_init(&pelstate, /* the state */ + key, /* user key */ + 32 /* key length in octets */ + )) != CRYPT_OK) { + printf("Error initializing Pelican: %s", error_to_string(err)); + return EXIT_FAILURE; + } + + /* MAC some data */ + if ((err = pelican_process(&pelstate, /* the state */ + "hello world", /* data to mac */ + 11 /* length of data */ + )) != CRYPT_OK) { + printf("Error processing Pelican: %s", error_to_string(err)); + return EXIT_FAILURE; + } + + /* Terminate the MAC */ + if ((err = pelican_done(&pelstate, /* the state */ + tag /* where to store the tag */ + )) != CRYPT_OK) { + printf("Error terminating Pelican: %s", error_to_string(err)); + return EXIT_FAILURE; + } + + /* tag[0..15] has the MAC output now */ + + return EXIT_SUCCESS; +} +\end{verbatim} + \chapter{Pseudo-Random Number Generators} \section{Core Functions} @@ -3359,16 +3728,6 @@ This will use libtool and gcc to build a shared library ``libtomcrypt.la'' as we 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 various high level macros which control the behaviour of the library. @@ -3391,36 +3750,36 @@ Currently LibTomCrypt will detect x86-32 and x86-64 running GCC as well as x86-3 \section{The Configure Script} There are also options you can specify from the configure script or ``mycrypt\_custom.h''. -\subsubsection{X memory routines} +\subsection{X memory 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} +\subsection{X clock routines} The rng\_get\_bytes() function can call a function that requires the clock() function. These macros let you override the default clock() used with a replacement. By default the standard C library clock() function is used. -\subsubsection{NO\_FILE} +\subsection{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\_NOP. This should help resolve any linker errors stemming from a lack of file I/O on embedded platforms. -\subsubsection{CLEAN\_STACK} +\subsection{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. -\subsubsection{LTC\_TEST} +\subsection{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} +\subsection{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. -\subsubsection{TWOFISH\_SMALL and TWOFISH\_TABLES} +\subsection{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 to allow some tradeoffs in the implementation. When TWOFISH\_SMALL is defined the scheduled symmetric key for Twofish requires only 200 bytes of memory. This is achieved by not pre-computing the substitution boxes. Having this @@ -3432,10 +3791,39 @@ useful when TWOFISH\_SMALL is defined as the table values are computed on the fl will increase by approximately 500 bytes. If this is defined but TWOFISH\_SMALL is not the cipher will still work but it will not speed up the encryption or decryption functions. -\subsubsection{SMALL\_CODE} +\subsection{GCM\_TABLES} +When defined GCM will use a 64KB table (per GCM state) which will greatly lower up the per--packet latency. +It also increases the initialization time. + +\subsection{SMALL\_CODE} 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. +\subsection{LTC\_FAST} +This mode (autodetected with x86\_32,x86\_64 platforms with GCC or MSVC) configures various routines such as ctr\_encrypt() or +cbc\_encrypt() that it can safely XOR multiple octets in one step by using a larger data type. This has the benefit of +cutting down the overhead of the respective functions. + +This mode does have one downside. It can cause unaligned reads from memory if you are not careful with the functions. This is why +it has been enabled by default only for the x86 class of processors where unaligned accesses are allowed. Technically LTC\_FAST +is not ``portable'' since unaligned accesses are not covered by the ISO C specifications. + +In practice however, you can use it on pretty much any platform (even MIPS) with care. + +By design the ``fast'' mode functions won't get unaligned on their own. For instance, if you call ctr\_encrypt() right after calling +ctr\_start() and all the inputs you gave are aligned than ctr\_encrypt() will perform aligned memory operations only. However, if you +call ctr\_encrypt() with an odd amount of plaintext then call it again the CTR pad (the IV) will be partially used. This will +cause the ctr routine to first use up the remaining pad bytes. Then if there are enough plaintext bytes left it will use +whole word XOR operations. These operations will be unaligned. + +The simplest precaution is to make sure you process all data in power of two blocks and handle ``remainder'' at the end. e.g. If you are +CTR'ing a long stream process it in blocks of (say) four kilobytes and handle any remaining incomplete blocks at the end of the stream. + +If you do plan on using the ``LTC\_FAST'' mode you have to also define a ``LTC\_FAST\_TYPE'' macro which resolves to an optimal sized +data type you can perform integer operations with. Ideally it should be four or eight bytes since it must properly divide the size +of your block cipher (e.g. 16 bytes for AES). This means sadly if you're on a platform with 57--bit words (or something) you can't +use this mode. So sad. + \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 @@ -3448,7 +3836,417 @@ to reduce the library size. Follow these steps \item Rebuild the library. \end{enumerate} +\chapter{Optimizations} +\section{Introduction} +The entire API was designed with plug and play in mind at the low level. That is you can swap out any cipher, hash or PRNG and dependent API will not require +updating. This has the nice benefit that I can add ciphers not have to re--write large portions of the API. For the most part LibTomCrypt has also been written +to be highly portable and easy to build out of the box on pretty much any platform. As such there are no assembler inlines throughout the code, I make no assumptions +about the platform, etc... +That works well for most cases but there are times where time is of the essence. This API also allows optimized routines to be dropped in--place of the existing +portable routines. For instance, hand optimized assembler versions of AES could be provided and any existing function that uses the cipher could automatically use +the optimized code without re--writing. This also paves the way for hardware drivers that can access hardware accelerated cryptographic devices. + +At the heart of this flexibility is the ``descriptor'' system. A descriptor is essentially just a C ``struct'' which describes the algorithm and provides pointers +to functions that do the work. For a given class of operation (e.g. cipher, hash, prng) the functions have identical prototypes which makes development simple. In most +dependent routines all a developer has to do is register\_XXX() the descriptor and they're set. + +\section{Ciphers} +The ciphers in LibTomCrypt are accessed through the ltc\_cipher\_descriptor structure. + +\begin{small} +\begin{verbatim} +struct ltc_cipher_descriptor { + /** name of cipher */ + char *name; + /** internal ID */ + unsigned char ID; + /** min keysize (octets) */ + int min_key_length, + /** max keysize (octets) */ + max_key_length, + /** block size (octets) */ + block_length, + /** default number of rounds */ + default_rounds; + /** Setup the cipher + @param key The input symmetric key + @param keylen The length of the input key (octets) + @param num_rounds The requested number of rounds (0==default) + @param skey [out] The destination of the scheduled key + @return CRYPT_OK if successful + */ + int (*setup)(const unsigned char *key, int keylen, + int num_rounds, symmetric_key *skey); + /** Encrypt a block + @param pt The plaintext + @param ct [out] The ciphertext + @param skey The scheduled key + */ + void (*ecb_encrypt)(const unsigned char *pt, + unsigned char *ct, symmetric_key *skey); + /** Decrypt a block + @param ct The ciphertext + @param pt [out] The plaintext + @param skey The scheduled key + */ + void (*ecb_decrypt)(const unsigned char *ct, + unsigned char *pt, symmetric_key *skey); + /** Test the block cipher + @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled + */ + int (*test)(void); + /** Determine a key size + @param keysize [in/out] The size of the key desired and the suggested size + @return CRYPT_OK if successful + */ + int (*keysize)(int *keysize); + +/** Accelerators **/ + /** Accelerated ECB encryption + @param pt Plaintext + @param ct Ciphertext + @param blocks The number of complete blocks to process + @param skey The scheduled key context + */ + void (*accel_ecb_encrypt)(const unsigned char *pt, + unsigned char *ct, unsigned long blocks, + symmetric_key *skey); + + /** Accelerated ECB decryption + @param pt Plaintext + @param ct Ciphertext + @param blocks The number of complete blocks to process + @param skey The scheduled key context + */ + void (*accel_ecb_decrypt)(const unsigned char *ct, + unsigned char *pt, unsigned long blocks, + symmetric_key *skey); + + /** Accelerated CBC encryption + @param pt Plaintext + @param ct Ciphertext + @param blocks The number of complete blocks to process + @param IV The initial value (input/output) + @param skey The scheduled key context + */ + void (*accel_cbc_encrypt)(const unsigned char *pt, + unsigned char *ct, unsigned long blocks, + unsigned char *IV, symmetric_key *skey); + + /** Accelerated CBC decryption + @param pt Plaintext + @param ct Ciphertext + @param blocks The number of complete blocks to process + @param IV The initial value (input/output) + @param skey The scheduled key context + */ + void (*accel_cbc_decrypt)(const unsigned char *ct, + unsigned char *pt, unsigned long blocks, + unsigned char *IV, symmetric_key *skey); + + /** Accelerated CTR encryption + @param pt Plaintext + @param ct Ciphertext + @param blocks The number of complete blocks to process + @param IV The initial value (input/output) + @param mode little or big endian counter (mode=0 or mode=1) + @param skey The scheduled key context + */ + void (*accel_ctr_encrypt)(const unsigned char *pt, + unsigned char *ct, unsigned long blocks, + unsigned char *IV, int mode, symmetric_key *skey); + + /** Accelerated CCM packet (one-shot) + @param key The secret key to use + @param keylen The length of the secret key (octets) + @param nonce The session nonce [use once] + @param noncelen The length of the nonce + @param header The header for the session + @param headerlen The length of the header (octets) + @param pt [out] The plaintext + @param ptlen The length of the plaintext (octets) + @param ct [out] The ciphertext + @param tag [out] The destination tag + @param taglen [in/out] The max size and resulting size of the authentication tag + @param direction Encrypt or Decrypt direction (0 or 1) + @return CRYPT_OK if successful + */ + void (*accel_ccm_memory)( + const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *header, unsigned long headerlen, + unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, unsigned long *taglen, + int direction); + + /** Accelerated GCM packet (one shot) + @param key The secret key + @param keylen The length of the secret key + @param IV The initial vector + @param IVlen The length of the initial vector + @param adata The additional authentication data (header) + @param adatalen The length of the adata + @param pt The plaintext + @param ptlen The length of the plaintext (ciphertext length is the same) + @param ct The ciphertext + @param tag [out] The MAC tag + @param taglen [in/out] The MAC tag length + @param direction Encrypt or Decrypt mode (GCM_ENCRYPT or GCM_DECRYPT) + */ + void (*accel_gcm_memory)( + const unsigned char *key, unsigned long keylen, + const unsigned char *IV, unsigned long IVlen, + const unsigned char *adata, unsigned long adatalen, + unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, unsigned long *taglen, + int direction); + +}; +\end{verbatim} +\end{small} + +\subsection{Name} +The ``name'' parameter specifies the name of the cipher. This is what a developer would pass to find\_cipher() to find the cipher in the descriptor +tables. + +\subsection{Internal ID} +This is a single byte Internal ID you can use to distingish ciphers from each other. + +\subsection{Key Lengths} +The minimum key length is ``min\_key\_length'' and is measured in octets. Similarly the maximum key length is ``max\_key\_length''. They can be equal +and both must valid key sizes for the cipher. Values in between are not assumed to be valid though they may be. + +\subsection{Block Length} +The size of the ciphers plaintext or ciphertext is ``block\_length'' and is measured in octets. + +\subsection{Rounds} +Some ciphers allow different number of rounds to be used. Usually you just use the default. The default round count is ``default\_rounds''. + +\subsection{Setup} +To initialize a cipher (for ECB mode) the function setup() was provided. It accepts an array of key octets ``key'' of length ``keylen'' octets. The user +can specify the number of rounds they want through ``num\_rounds'' where $num\_rounds = 0$ means use the default. The destination of a scheduled key is stored +in ``skey''. + +This is where things get tricky. Currently there is no provision to allocate memory during initialization since there is no ``cipher done'' function. So you have +to either use an existing member of the symmetric\_key union or alias your own structure over top of it provided symmetric\_key is not smaller. + +\subsection{Single block ECB} +To process a single block in ECB mode the ecb\_encrypt() and ecb\_decrypt() functions were provided. The plaintext and ciphertext buffers are allowed to overlap so you +must make sure you do not overwrite the output before you are finished with the input. + +\subsection{Testing} +The test() function is used to self--test the ``device''. It takes no arguments and returns \textbf{CRYPT\_OK} if all is working properly. + +\subsection{Key Sizing} +Occasionally a function will want to find a suitable key size to use since the input is oddly sized. The keysize() function is for this case. It accepts a +pointer to an integer which represents the desired size. The function then has to match it to the exact or a lower key size that is valid for the cipher. For +example, if the input is $25$ and $24$ is valid then it stores $24$ back in the pointed to integer. It must not round up and must return an error if the keysize + cannot be mapped to a valid key size for the cipher. + +\subsection{Acceleration} +The next set of functions cover the accelerated functionality of the cipher descriptor. Any combination of these functions may be set to \textbf{NULL} to indicate +it is not supported. In those cases the software fallbacks are used (using the single ECB block routines). + +\subsubsection{Accelerated ECB} +These two functions are meant for cases where a user wants to encrypt (in ECB mode no less) an array of blocks. These functions are accessed +through the accel\_ecb\_encrypt and accel\_ecb\_decrypt pointers. The ``blocks'' count is the number of complete blocks to process. + +\subsubsection{Accelerated CBC} +These two functions are meant for accelerated CBC encryption. These functions are accessed through the accel\_cbc\_encrypt and accel\_cbc\_decrypt pointers. +The ``blocks'' value is the number of complete blocks to process. The ``IV'' is the CBC initial vector. It is an input upon calling this function and must be +updated by the function before returning. + +\subsubsection{Accelerated CTR} +This function is meant for accelerated CTR encryption. It is accessible through the accel\_ctr\_encrypt pointer. +The ``blocks'' value is the number of complete blocks to process. The ``IV'' is the CTR counter vector. It is an input upon calling this function and must be +updated by the function before returning. The ``mode'' value indicates whether the counter is big ($mode = 1$) or little ($mode = 0$) endian. + +This function (and the way it's called) differs from the other two since ctr\_encrypt() allows any size input plaintext. The accelerator will only be +called if the following conditions are met. + +\begin{enumerate} + \item The accelerator is present + \item The CTR pad is empty + \item The remaining length of the input to process is greater than or equal to the block size. +\end{enumerate} + +The ``CTR pad'' is empty when a multiple (including zero) blocks of text have been processed. That is, if you pass in seven bytes to AES--CTR mode you would have to +pass in a minimum of nine extra bytes before the accelerator could be called. The CTR accelerator must increment the counter (and store it back into the +buffer provided) before encrypting it to create the pad. + +The accelerator will only be used to encrypt whole blocks. Partial blocks are always handled in software. + +\subsubsection{Accelerated CCM} +This function is meant for accelerated CCM encryption or decryption. It processes the entire packet in one call. Note that the setup() function will not +be called prior to this. This function must handle scheduling the key provided on its own. + +\subsubsection{Accelerated GCM} +This function is meant for accelerated GCM encryption or decryption. It processes the entire packet in one call. Note that the setup() function will not +be called prior to this. This function must handle scheduling the key provided on its own. + +\section{One--Way Hashes} +The hash functions are accessed through the ltc\_hash\_descriptor structure. + +\begin{small} +\begin{verbatim} +struct ltc_hash_descriptor { + /** name of hash */ + char *name; + /** internal ID */ + unsigned char ID; + /** Size of digest in octets */ + unsigned long hashsize; + /** Input block size in octets */ + unsigned long blocksize; + /** ASN.1 DER identifier */ + unsigned char DER[64]; + /** Length of DER encoding */ + unsigned long DERlen; + /** Init a hash state + @param hash The hash to initialize + @return CRYPT_OK if successful + */ + int (*init)(hash_state *hash); + /** Process a block of data + @param hash The hash state + @param in The data to hash + @param inlen The length of the data (octets) + @return CRYPT_OK if successful + */ + int (*process)(hash_state *hash, const unsigned char *in, unsigned long inlen); + /** Produce the digest and store it + @param hash The hash state + @param out [out] The destination of the digest + @return CRYPT_OK if successful + */ + int (*done)(hash_state *hash, unsigned char *out); + /** Self-test + @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled + */ + int (*test)(void); +}; +\end{verbatim} +\end{small} + +\subsection{Name} +This is the name the hash is known by and what find\_hash() will look for. + +\subsection{Internal ID} +This is the internal ID byte used to distinguish the hash from other hashes. + +\subsection{Digest Size} +The ``hashsize'' variable indicates the length of the output in octets. + +\subsection{Block Size} +The `blocksize'' variable indicates the length of input (in octets) that the hash processes in a given +invokation. + +\subsection{DER Identifier} +This is the DER identifier (including the SEQUENCE header). This is used solely for PKCS \#1 style signatures. + +\subsection{Initialization} +The init function initializes the hash and prepares it to process message bytes. + +\subsection{Process} +This processes message bytes. The algorithm must accept any length of input that the hash would allow. The input is not +guaranteed to be a multiple of the block size in length. + +\subsection{Done} +The done function terminates the hash and returns the message digest. + +\subsection{Acceleration} +A compatible accelerator must allow processing data in any granularity which may require internal padding on the driver side. + +\section{Pseudo--Random Number Generators} +The pseudo--random number generators are accessible through the ltc\_prng\_descriptor structure. + +\begin{small} +\begin{verbatim} +struct ltc_prng_descriptor { + /** Name of the PRNG */ + char *name; + /** size in bytes of exported state */ + int export_size; + /** Start a PRNG state + @param prng [out] The state to initialize + @return CRYPT_OK if successful + */ + int (*start)(prng_state *prng); + /** Add entropy to the PRNG + @param in The entropy + @param inlen Length of the entropy (octets)\ + @param prng The PRNG state + @return CRYPT_OK if successful + */ + int (*add_entropy)(const unsigned char *in, unsigned long inlen, prng_state *prng); + /** Ready a PRNG state to read from + @param prng The PRNG state to ready + @return CRYPT_OK if successful + */ + int (*ready)(prng_state *prng); + /** Read from the PRNG + @param out [out] Where to store the data + @param outlen Length of data desired (octets) + @param prng The PRNG state to read from + @return Number of octets read + */ + unsigned long (*read)(unsigned char *out, unsigned long outlen, prng_state *prng); + /** Terminate a PRNG state + @param prng The PRNG state to terminate + @return CRYPT_OK if successful + */ + int (*done)(prng_state *prng); + /** Export a PRNG state + @param out [out] The destination for the state + @param outlen [in/out] The max size and resulting size of the PRNG state + @param prng The PRNG to export + @return CRYPT_OK if successful + */ + int (*pexport)(unsigned char *out, unsigned long *outlen, prng_state *prng); + /** Import a PRNG state + @param in The data to import + @param inlen The length of the data to import (octets) + @param prng The PRNG to initialize/import + @return CRYPT_OK if successful + */ + int (*pimport)(const unsigned char *in, unsigned long inlen, prng_state *prng); + /** Self-test the PRNG + @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled + */ + int (*test)(void); +}; +\end{verbatim} +\end{small} + +\subsection{Name} +The name by which find\_prng() will find the PRNG. + +\subsection{Export Size} +When an PRNG state is to be exported for future use you specify the space required in this variable. + +\subsection{Start} +Initialize the PRNG and make it ready to accept entropy. + +\subsection{Entropy Addition} +Add entropy to the PRNG state. The exact behaviour of this function depends on the particulars of the PRNG. + +\subsection{Ready} +This function makes the PRNG ready to read from by processing the entropy added. The behaviour of this function depends +on the specific PRNG used. + +\subsection{Read} +Read from the PRNG and return the number of bytes read. This function does not have to fill the buffer but it is best +if it does as many protocols do not retry reads and will fail on the first try. + +\subsection{Done} +Terminate a PRNG state. The behaviour of this function depends on the particular PRNG used. + +\subsection{Exporting and Importing} +An exported PRNG state is data that the PRNG can later import to resume activity. They're not meant to resume ``the same session'' +but should at least maintain the same level of state entropy. \input{crypt.ind} diff --git a/demos/test.c b/demos/test.c new file mode 100644 index 0000000..290861d --- /dev/null +++ b/demos/test.c @@ -0,0 +1,19 @@ +#include + +int main(void) +{ + reg_algs(); + printf("build == \n%s\n", crypt_build_settings); + printf("\ncipher_test..."); fflush(stdout); printf(cipher_hash_test() ? "failed" : "passed"); + printf("\nmodes_test..."); fflush(stdout); printf(modes_test() ? "failed" : "passed"); + printf("\nmac_test..."); fflush(stdout); printf(mac_test() ? "failed" : "passed"); + printf("\npkcs_1_test..."); fflush(stdout); printf(pkcs_1_test() ? "failed" : "passed"); + printf("\nstore_test..."); fflush(stdout); printf(store_test() ? "failed" : "passed"); + printf("\nrsa_test..."); fflush(stdout); printf(rsa_test() ? "failed" : "passed"); + printf("\necc_test..."); fflush(stdout); printf(ecc_tests() ? "failed" : "passed"); + printf("\ndsa_test..."); fflush(stdout); printf(dsa_test() ? "failed" : "passed"); + printf("\ndh_test..."); fflush(stdout); printf(dh_tests() ? "failed" : "passed"); + printf("\nder_test..."); fflush(stdout); printf(der_tests() ? "failed" : "passed"); + + return EXIT_SUCCESS; +} diff --git a/demos/test/.ccmalloc b/demos/test/.ccmalloc deleted file mode 100644 index 1b0aba2..0000000 --- a/demos/test/.ccmalloc +++ /dev/null @@ -1,356 +0,0 @@ - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - %%%% generic configuration file for %%%% - %%%% the ccmalloc memory profiler %%%% - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - %-----------------------------------------------------------------% - % COPY THIS FILE TO '.ccmalloc' in your project or home directory % - %-----------------------------------------------------------------% - -############################################################################## -## (C) 1997-2003 Armin Biere, 1998 Johannes Keukelaar -## $Id: ccmalloc.cfg,v 1.6 2003/02/03 08:03:54 biere Exp $ -############################################################################## - -%%% '%' and '#' are comments !!!!!!! - -% This file must be called '.ccmalloc' and is searched for in the -% current directory and in the home directory of the user. If it -% does not exist then the default values mentioned below are used. - -% It is also the only available user manual yet ;-) So here is a reading -% hint. First have a look at the short one line descriptions of each option -% ... - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% with 'file' the executable is specified [a.out] -% ---------------------------------------------------------------------- -% This should not be necessary for Linux and Solaris because the proc -% file system can be used to find argv[0]. -% -% (the rest of this comment only applies to other OS) -% -% For other OS you should use this option unless the executable is -% in the current directory or its name is 'a.out'. -% -% If you do not specify this then ccmalloc tries to find an executable -% in the current directory that matches the running program starting -% with 'a.out'. For this process it must call 'nm' on each executable -% file in the directory which may be time consuming. With this option -% you can speed up this process. -% -% You can also specify absolute or relative path names. This is -% necessary if you do not start your program from the current directory. -% But you can also simply link or name your program to 'a.out'. - -%file FILE - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% 'log' specify the logfile [stderr] -% ---------------------------------------------------------------------- -% The default is to use stderr. The argument to 'log' is the name of -% the file you want to write to. It can also be 'stdout' or '-' which -% sets stdout as logfile. If the logfile is stdout or stderr and is -% connected to a terminal then the output is slightly different. -% -% For big programs the logfile can be really big. To reduce the size -% you can use a small chain length (see 'chain-length' below). The other -% possibility is to use compressed logfiles. This can be done by -% specifying a logfile name with a '.gz' (or a '.Z') suffix. This means -% that gnuzip (resp. compress) is used to compress the output. - -%log FILE - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% 'logpid' specify the logfile -% ---------------------------------------------------------------------- -% Can be used alternatively to the 'log' command if you want to use -% ccmalloc for debugging parallel applications where several copies of -% the program you are debugging must be run simoultaneously. In this -% case you can not use 'log' because you do not want to write to the same -% log file. Using 'logpid' uses a file name ending with the of -% the process which means the name is unique even if several copies of -% your program are run simoultaneously. -% -% If you use the compressing suffixes then the is inserted before -% the suffix (e.g. 'logpid ccmalloc.log.gz' uses 'ccmalloc.log..gz' -% as the name for the log file). - -%logpid FILE - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% 'dont-log-chain' skip info about certain chains [] -% ---------------------------------------------------------------------- -% This command may be repeated any number of times. The argument to this -% command is a comma-separated list of function-or-file-and-line -% specifications. Garbage allocated from a callchain that contains this -% subchain anywhere will _not_ be logged. -% -% The ';'-separated list should not contain any spaces. E.g. not: -% -% main ; foo ; bar -% -% but: -% -% main;foo;bar -% -% A function-or-file-and-line specification is a string followed by an -% optional colon and number, for example: main or main:14 or main.c or -% main.c:15. Note that the string is compared with both the function and the -% file name, if available. If main.c happens to be a function name, that -% will cause a match (for that string at least). Not specifying a line -% number will match any line number. If line number information is not -% available, anything will match! Not specifying a name (e.g. ;;;) will -% match an unknown function name. Not giving any parameters at all, will -% match a chain containing at least one unknown function. -% -% Note that if you say 'dont-log-chain wrapper.c' nothing will be logged. - -%dont-log-chain - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% 'only-log-chain' skip info about other chains [] -% ---------------------------------------------------------------------- -% The obvious counterpart to dont-log-chain. In this case, only matching -% chains will be reported. Non-matching chains will not be reported. -% Can be repeated any number of times; if the chain matches any of the -% instances, it will be reported. - -%only-log-chain - -######################################################################## -# # -# This is the 'flag' section # -# # -# 'set FLAG' is the same as 'set FLAG 1' # -# # -# The default values are those set below. If 'silent' is disabled # -# then you will find the banner in the log file (or it is listed on # -# stdout or stderr). The banner describes the current settings of all # -# these flags. # -# # -######################################################################## - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% with 'only-count' ccmalloc only counts garbage - no call chains [0] -% ---------------------------------------------------------------------- -% If only-count is set to one then only one additional pointer for -% each allocated data is used and no call chain is generated. This is -% the fasted and most space efficient mode ccmalloc can operate -% in. In this mode you get at least the size of garbage produced. -% -% Note that 'check-free-space' does not work at all with 'only-count' -% set and over writes ('check-overwrites') are only checked when -% calling free. - -%set only-count 0 - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% 'load-dynlibs' load dynamic linked libraries into gdb [0] -% ---------------------------------------------------------------------- -% If your program is linked with dynamic libraries, function and file -% name information is not available for addresses in those libraries, -% unless you set 'load-dynlibs' to 1. - -%set load-dynlibs 0 - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% 'keep-deallocated-data' does not recycle deallocated data [0] -% ---------------------------------------------------------------------- -% If you enable keep-deallocated-data then all data deallocated with -% 'free' (or 'delete' in C++) is not given back to the free store -% but stays associated with the call chain of its allocation. This is -% very useful if your program does multiple deallocation of the -% same data. - -%set keep-deallocated-data 0 - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% 'check-overwrites' detect overwrites [0] -% ---------------------------------------------------------------------- -% If you want to detect 'off by n bytes' errors you should set -% 'checking-overwrites' to n/4 (on 32-Bit machines). -% -% ccmalloc inserts a boundary above allocated data. This boundary -% consists of 'check-overwrites' words. If your program writes to -% this area then ccmalloc can detect this (see also check-start -% and check-interval). 'ccmalloc' also does checking for overwrites -% at non word boundaries (e.g. strcpy(malloc(strlen("hello")),"hello");) - -set check-overwrites 1 - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% 'check-underwrites' detect underwrites [0] -% ---------------------------------------------------------------------- -% same with writes below allocated data. You do not have to set this -% option if you only want detect 'off (below) by one' errors because -% ccmalloc keeps a magic value just before the user data. - -set check-underwrites 1 - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% 'check-free-space' can be used to find dangling pointers. [0] -% ---------------------------------------------------------------------- -% A very serious type of bug is to write on data that has already been -% freed. If this happens the free space management of malloc is in -% trouble and you will perhaps encounter non deterministic behaviour of -% your program. To test this first enable 'keep-deallocated-data' and -% restart your program. If the problem goes away and ccmalloc does not -% report anything then you should *also* enable 'check-free-space'. Now -% ccmalloc checks already deallocated data for corruption. -% -% Note that to perform this check 'keep-deallocated-data' also must -% be enabled and 'only-count' disabled. - -set check-free-space 1 - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% 'check-interval' can be used to speed up checks [0] -% ---------------------------------------------------------------------- -% If check-overwrite, check-underwrites or check-free-space is set then -% the default is to do 'write checks' when data is deallocated and -% to do 'free space checks' when reporting together with -% 'write checks' for garbage. When you want these checks to be -% performed more often then you should set 'check-interval' to a -% positive number. This number is the interval between the number of -% calls to free or malloc without performing the checks. - -%set check-interval 0 - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% 'check-start' can be used to speed up checks [0] -% ---------------------------------------------------------------------- -% The flag 'check-start' delays the start of checks until the given -% number of calls to free and malloc have occured. Together with -% 'check-interval' you can use a binary search to find an aproximation -% when a corruption occured! If you simply set check-interval to 1 and -% check-start to 0 then this will slow done your program too much. - -%set check-start 0 - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% 'silent' disables banner [0] -% ---------------------------------------------------------------------- -% If you don't want to see the banner of ccmalloc then set -% 'silent' to 1 (f.e. when logging to stderr) - -%set silent - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% 'file-info' en/disables file and line number information [1] -% ---------------------------------------------------------------------- -% If your program was compiled with debugging information (-g) then -% ccmalloc can generate line number and file info for call chains opening -% a pipe to gdb. For very big programs this method is slow. In this case -% you can set 'file-info' to zero and you will only get the function -% names. For SunOS 4.3.1 'nm' does not 'demangle' C++ identifiers -% very well. So gdb is called instead but only if 'file-info' is -% not set to 0. - -%set file-info 1 - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% 'continue' if ccmalloc aborts when something weired happened [0] -% ---------------------------------------------------------------------- -% If the free function of ccmalloc is called with an argument that does -% not make sense to ccmalloc or that has already been freed then you -% probably want the program to stop at this point. This is also -% the default behaviour. But you can force ccmalloc also to ignore -% this if you set 'continue' to 1. This flag also controls the behaviour -% of ccmalloc when free space is found to be corrupted or a write -% boundary has been overwritten. - -%set continue 0 - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% 'chain-length' is the length of the maximal call chain [0 = infinite] -% ---------------------------------------------------------------------- -% You can restrict the length of call chains by setting 'chain-length' -% to a number greater than zero. If 'chain-length' is zero (the default) -% then chains are as long as possible (on a non x86 system only call -% chains with a finite maximal length can be generated). For big -% programs especially if keep-deallocated-data is enabled this can -% reduce the size of the log file from over 100MB to several MB! - -%set chain-length 0 - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% 'print-addresses' of data [0] -% ---------------------------------------------------------------------- -% If you want to see the addresses of the allocated data (and -% deallocated data if keep-deallocated-data is set to 1) set -% 'print-addresses' to 1. - -%set print-addresses 0 - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% 'print-on-one-line' shortens log file [0] -% ---------------------------------------------------------------------- -% The default is to print function names and file/line number info -% on separate lines. With 'print-on-one-line' set 1 all are printed -% on one line. - -%set print-on-one-line 0 - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% 'additional-line' enlarges readability [1] -% ---------------------------------------------------------------------- -% When printing call chains an empty line is printed between to -% call points. Set 'additional-line' to 0 to disable this feature. - -%set additional-line 1 - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% 'statistics' enables more accurate profiling [0] -% ---------------------------------------------------------------------- -% Calculate number of allocations and deallocations and bytes also on -% a per call chain basis. This uses 4 additional pointers for each -% call chain. - -set statistics 1 - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% set order for sorting of call chains [1] [1] -% ---------------------------------------------------------------------- -% When printing the report to the log file the call chains are sorted by -% default with respect to the largest accumulated garbage produced by -% that call chain. This can be changed with setting 'sort-by-wasted' -% to 0. In this case they are sorted by the number of allocated bytes. -% If you want the number of allocations (only possible if 'statistics' -% is enabled) as sorting criteria instead then set 'sort-by-size' to 0. - -%set sort-by-wasted 1 -%set sort-by-size 1 - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% report library chains [0] -% ---------------------------------------------------------------------- -% Some external libraries (like libg++) have memory leaks. On some -% systems even a call to printf produces a leak. ccmalloc tries to -% detect this (only heuristically!) and with this flag you can control -% if leaks produced by such library calls are reported. -% -% Since version 0.2.1 some similar effect can be achieved by using -% 'dont-log-chain' with no argument. - -%set library-chains 0 - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% print debugging information [X] (compile time dependend) -% ---------------------------------------------------------------------- - -%set debug X - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% align memory on 8 byte boundary [0] (no effect on SunOS or Solaris) -% ---------------------------------------------------------------------- - -%set align-8-byte 0 - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% only report allocations which ended up being wasted (i.e don't report -% allocations which were completely freed properly. ) [1] -% ---------------------------------------------------------------------- - -%set only-wasting-alloc 1 diff --git a/demos/test/mac_test.c b/demos/test/mac_test.c deleted file mode 100644 index 52e75d8..0000000 --- a/demos/test/mac_test.c +++ /dev/null @@ -1,12 +0,0 @@ -/* test pmac/omac/hmac */ -#include "test.h" - -int mac_test(void) -{ - DO(hmac_test()); - DO(pmac_test()); - DO(omac_test()); - DO(eax_test()); - DO(ocb_test()); - return 0; -} diff --git a/demos/test/makefile b/demos/test/makefile deleted file mode 100644 index 7351548..0000000 --- a/demos/test/makefile +++ /dev/null @@ -1,25 +0,0 @@ -# make test harness, it is good. -CFLAGS += -Wall -W -Os -I../../src/headers/ -I./ - -# add -g3 for ccmalloc debugging -#CFLAGS += -g3 - -# if you're not debugging -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.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] -# -# -#CCMALLOC = -lccmalloc -ldl - -test: $(OBJECTS) - $(CC) $(CFLAGS) $(OBJECTS) /usr/lib/libtomcrypt.a $(CCMALLOC) -o test - -clean: - rm -rf test *.o *.obj *.exe *~ .libs diff --git a/demos/test/makefile.icc b/demos/test/makefile.icc deleted file mode 100644 index b69c997..0000000 --- a/demos/test/makefile.icc +++ /dev/null @@ -1,14 +0,0 @@ -# make test harness, it is good. -CFLAGS += -O3 -xN -ip -I../../src/headers/ -I./ -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.o dh_tests.o der_tests.o - -test: $(OBJECTS) - $(CC) $(OBJECTS) -ltomcrypt -o test - -clean: - rm -f test *.o *~ diff --git a/demos/test/makefile.msvc b/demos/test/makefile.msvc deleted file mode 100644 index 7d04b86..0000000 --- a/demos/test/makefile.msvc +++ /dev/null @@ -1,14 +0,0 @@ -# make test harness, it is good. -CFLAGS = $(CFLAGS) /W3 /Ox /I../../src/headers/ /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 der_tests.obj - - -test.exe: $(OBJECTS) - cl $(OBJECTS) tomcrypt.lib advapi32.lib - -clean: - rm -f test.exe *.obj *~ diff --git a/demos/test/makefile.shared b/demos/test/makefile.shared deleted file mode 100644 index 9f46713..0000000 --- a/demos/test/makefile.shared +++ /dev/null @@ -1,19 +0,0 @@ -# make test harness, it is good. -CFLAGS += -Wall -W -Os -I../../src/headers/ -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/test.c b/demos/test/test.c deleted file mode 100644 index b28990d..0000000 --- a/demos/test/test.c +++ /dev/null @@ -1,271 +0,0 @@ -#include "test.h" - -test_entry tests[26]; - -test_entry test_list[26] = { - -/* test name provides requires entry */ -{"store_test", "a", "", store_test }, -{"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", "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} -}; - -prng_state test_yarrow; -static int current_test; - -void run_cmd(int res, int line, char *file, char *cmd) -{ - if (res != CRYPT_OK) { - fprintf(stderr, "[%s]: %s (%d)\n%s:%d:%s\n", tests[current_test].name, error_to_string(res), res, file, line, cmd); - exit(EXIT_FAILURE); - } -} - -void register_algs(void) -{ - int err; - -#ifdef RIJNDAEL - register_cipher (&aes_desc); -#endif -#ifdef BLOWFISH - register_cipher (&blowfish_desc); -#endif -#ifdef XTEA - register_cipher (&xtea_desc); -#endif -#ifdef RC5 - register_cipher (&rc5_desc); -#endif -#ifdef RC6 - register_cipher (&rc6_desc); -#endif -#ifdef SAFERP - register_cipher (&saferp_desc); -#endif -#ifdef TWOFISH - register_cipher (&twofish_desc); -#endif -#ifdef SAFER - register_cipher (&safer_k64_desc); - register_cipher (&safer_sk64_desc); - register_cipher (&safer_k128_desc); - register_cipher (&safer_sk128_desc); -#endif -#ifdef RC2 - register_cipher (&rc2_desc); -#endif -#ifdef DES - register_cipher (&des_desc); - register_cipher (&des3_desc); -#endif -#ifdef CAST5 - register_cipher (&cast5_desc); -#endif -#ifdef NOEKEON - register_cipher (&noekeon_desc); -#endif -#ifdef SKIPJACK - register_cipher (&skipjack_desc); -#endif -#ifdef KHAZAD - register_cipher (&khazad_desc); -#endif -#ifdef ANUBIS - register_cipher (&anubis_desc); -#endif - -#ifdef TIGER - register_hash (&tiger_desc); -#endif -#ifdef MD2 - register_hash (&md2_desc); -#endif -#ifdef MD4 - register_hash (&md4_desc); -#endif -#ifdef MD5 - register_hash (&md5_desc); -#endif -#ifdef SHA1 - register_hash (&sha1_desc); -#endif -#ifdef SHA256 - register_hash (&sha256_desc); -#endif -#ifdef SHA224 - register_hash (&sha224_desc); -#endif -#ifdef SHA384 - register_hash (&sha384_desc); -#endif -#ifdef SHA512 - register_hash (&sha512_desc); -#endif -#ifdef RIPEMD128 - register_hash (&rmd128_desc); -#endif -#ifdef RIPEMD160 - register_hash (&rmd160_desc); -#endif -#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); -#endif -#ifdef FORTUNA - register_prng(&fortuna_desc); -#endif -#ifdef RC4 - register_prng(&rc4_desc); -#endif -#ifdef SPRNG - register_prng(&sprng_desc); -#endif -#ifdef SOBER128 - register_prng(&sober128_desc); -#endif -} - -/* sort tests based on their requirement/services. Helps make sure dependencies are tested first */ -void sort(void) -{ - unsigned x, y, z, a, pidx[26]; - - /* find out where things are provided */ - zeromem(pidx, sizeof(pidx)); - z = 0; - do { - y = 0; - for (x = 0; test_list[x].name != NULL; x++) { - if (test_list[x].entry == NULL) continue; - if (strlen(test_list[x].prov) == 0) { - y = 1; - tests[z++] = test_list[x]; test_list[x].entry = NULL; - pidx[test_list[x].prov[0]-'a'] = 1; - break; - } else { - for (a = 0; a < strlen(test_list[x].req); a++) { - if (pidx[test_list[x].req[a]-'a'] == 0) break; - } - if (a == strlen(test_list[x].req)) { - y = 1; - tests[z++] = test_list[x]; test_list[x].entry = NULL; - pidx[test_list[x].prov[0]-'a'] = 1; - break; - } - } - } - } while (y == 1); -} - -#define STACKBLOCK 8 -#define STACK_EST_USAGE 32768 - -unsigned char stack_mask[STACKBLOCK]; -unsigned long stack_cur=0; - -void stack_masker(void) -{ -#ifdef STACK_TEST - volatile unsigned char M[STACK_EST_USAGE]; - stack_cur = 0; - for (stack_cur = 0; stack_cur < STACK_EST_USAGE/STACKBLOCK; stack_cur++) { - memcpy(M+(stack_cur*STACKBLOCK), stack_mask, STACKBLOCK); - } -#endif -} - -void stack_check(void) -{ -#ifdef STACK_TEST - unsigned char M[STACK_EST_USAGE]; - stack_cur = 0; -#ifdef STACK_DOWN - while (memcmp(M+(STACK_EST_USAGE-STACKBLOCK-stack_cur), stack_mask, STACKBLOCK) && -#else - while (memcmp(M+stack_cur, stack_mask, STACKBLOCK) && -#endif - stack_cur < (STACK_EST_USAGE - STACKBLOCK)) { - ++stack_cur; - } -#endif -} - -int main(void) -{ - int x; - unsigned char buf[16]; - - /* setup stack checker */ - srand(time(NULL)); - for (x = 0; x < STACKBLOCK; x++) { - stack_mask[x] = rand() & 255; - } - stack_masker(); - - printf("Built with\n%s\n", crypt_build_settings); - - sort(); - register_algs(); - - // start dummy yarrow for internal use - DO(yarrow_start(&test_yarrow)); - sprng_read(buf, 16, NULL); - DO(yarrow_add_entropy(buf, 16, &test_yarrow)); - DO(yarrow_ready(&test_yarrow)); - - // output sizes (this will crash MSVC... go figure.) -#ifndef _MSC_VER - printf("Sizes of objects (in bytes)\n"); - printf("\tsymmetric_key\t=\t%5Zu\n", sizeof(symmetric_key)); - printf("\thash_state\t=\t%5Zu\n", sizeof(hash_state)); - printf("\thmac_state\t=\t%5Zu\n", sizeof(hmac_state)); - printf("\tomac_state\t=\t%5Zu\n", sizeof(omac_state)); - printf("\tpmac_state\t=\t%5Zu\n", sizeof(pmac_state)); - printf("\tocb_state\t=\t%5Zu\n", sizeof(ocb_state)); - printf("\teax_state\t=\t%5Zu\n", sizeof(eax_state)); - printf("\tmp_int\t\t=\t%5Zu\n", sizeof(mp_int)); -#ifdef MRSA - printf("\trsa_key\t\t=\t%5Zu\n", sizeof(rsa_key)); -#endif -#ifdef MDSA - printf("\tdsa_key\t\t=\t%5Zu\n", sizeof(dsa_key)); -#endif -#ifdef MDH - printf("\tdh_key\t\t=\t%5Zu\n", sizeof(dh_key)); -#endif -#ifdef MECC - printf("\tecc_key\t\t=\t%5Zu\n", sizeof(ecc_key)); -#endif - printf("\n\n"); -#endif - - // do tests - for (current_test = 0; tests[current_test].name != NULL; current_test++) { - printf("[%-20s]: ", tests[current_test].name); fflush(stdout); - printf("\t%s\n", tests[current_test].entry()==0?"passed":"failed"); - } - - return 0; -} diff --git a/demos/test/test.h b/demos/test/test.h deleted file mode 100644 index 9c0ed6f..0000000 --- a/demos/test/test.h +++ /dev/null @@ -1,41 +0,0 @@ - -#ifndef __TEST_H_ -#define __TEST_H_ - -#include "tomcrypt.h" - -/* enable stack testing */ -// #define STACK_TEST - -/* stack testing, define this if stack usage goes downwards [e.g. x86] */ -#define STACK_DOWN - -typedef struct { - char *name, *prov, *req; - int (*entry)(void); -} test_entry; - -extern prng_state test_yarrow; - - -void stack_masker(void); -void stack_check(void); -extern unsigned long stack_cur; -#define stack_chk(x) { stack_check(); if (stack_cur >= 1024) { fprintf(stderr, " Warning: Stack usage of %lu in %s, %s:%d\n", stack_cur, x, __FILE__, __LINE__); } } - -void run_cmd(int res, int line, char *file, char *cmd); -#define DO(x) { stack_masker(); run_cmd((x), __LINE__, __FILE__, #x); stack_chk(#x); } - -/* TESTS */ -int cipher_hash_test(void); -int modes_test(void); -int mac_test(void); -int pkcs_1_test(void); -int store_test(void); -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/timing.c b/demos/timing.c new file mode 100644 index 0000000..54c0462 --- /dev/null +++ b/demos/timing.c @@ -0,0 +1,23 @@ +#include + +int main(void) +{ +init_timer(); +reg_algs(); +time_keysched(); +time_cipher(); +time_cipher2(); +time_cipher3(); +time_hash(); +time_macs(); +time_encmacs(); +time_prng(); +time_mult(); +time_sqr(); +time_rsa(); +time_ecc(); +time_dh(); + +return EXIT_SUCCESS; + +} diff --git a/demos/tv_gen.c b/demos/tv_gen.c index 5a778d0..c37d1af 100644 --- a/demos/tv_gen.c +++ b/demos/tv_gen.c @@ -501,6 +501,127 @@ void ocb_gen(void) fclose(out); } + +void ccm_gen(void) +{ + int err, kl, x, y1, z; + FILE *out; + unsigned char key[MAXBLOCKSIZE], nonce[MAXBLOCKSIZE*2], + plaintext[MAXBLOCKSIZE*2], tag[MAXBLOCKSIZE]; + unsigned long len; + + out = fopen("ccm_tv.txt", "w"); + fprintf(out, "CCM Test Vectors. Uses the 00010203...NN-1 pattern for nonce/header/plaintext/key. The outputs\n" + "are of the form ciphertext,tag for a given NN. The key for step N>1 is the tag of the previous\n" + "step repeated sufficiently. The nonce is fixed throughout at 13 bytes 000102...\n\n"); + + for (x = 0; cipher_descriptor[x].name != NULL; x++) { + kl = cipher_descriptor[x].block_length; + + /* skip ciphers which do not have 128 bit block sizes */ + if (kl != 16) continue; + + if (cipher_descriptor[x].keysize(&kl) != CRYPT_OK) { + kl = cipher_descriptor[x].max_key_length; + } + fprintf(out, "CCM-%s (%d byte key)\n", cipher_descriptor[x].name, kl); + + /* the key */ + for (z = 0; z < kl; z++) { + key[z] = (z & 255); + } + + /* fixed nonce */ + for (z = 0; z < cipher_descriptor[x].block_length; z++) { + nonce[z] = z; + } + + for (y1 = 0; y1 <= (int)(cipher_descriptor[x].block_length*2); y1++){ + for (z = 0; z < y1; z++) { + plaintext[z] = (unsigned char)(z & 255); + } + len = sizeof(tag); + if ((err = ccm_memory(x, key, kl, nonce, 13, plaintext, y1, plaintext, y1, plaintext, tag, &len, CCM_ENCRYPT)) != CRYPT_OK) { + printf("Error CCM'ing: %s\n", error_to_string(err)); + exit(EXIT_FAILURE); + } + fprintf(out, "%3d: ", y1); + for (z = 0; z < y1; z++) { + fprintf(out, "%02X", plaintext[z]); + } + fprintf(out, ", "); + for (z = 0; z <(int)len; z++) { + fprintf(out, "%02X", tag[z]); + } + fprintf(out, "\n"); + + /* forward the key */ + for (z = 0; z < kl; z++) { + key[z] = tag[z % len]; + } + } + fprintf(out, "\n"); + } + fclose(out); +} + +void gcm_gen(void) +{ + int err, kl, x, y1, z; + FILE *out; + unsigned char key[MAXBLOCKSIZE], plaintext[MAXBLOCKSIZE*2], tag[MAXBLOCKSIZE]; + unsigned long len; + + out = fopen("gcm_tv.txt", "w"); + fprintf(out, "GCM Test Vectors. Uses the 00010203...NN-1 pattern for nonce/header/plaintext/key. The outputs\n" + "are of the form ciphertext,tag for a given NN. The key for step N>1 is the tag of the previous\n" + "step repeated sufficiently. The nonce is fixed throughout at 13 bytes 000102...\n\n"); + + for (x = 0; cipher_descriptor[x].name != NULL; x++) { + kl = cipher_descriptor[x].block_length; + + /* skip ciphers which do not have 128 bit block sizes */ + if (kl != 16) continue; + + if (cipher_descriptor[x].keysize(&kl) != CRYPT_OK) { + kl = cipher_descriptor[x].max_key_length; + } + fprintf(out, "GCM-%s (%d byte key)\n", cipher_descriptor[x].name, kl); + + /* the key */ + for (z = 0; z < kl; z++) { + key[z] = (z & 255); + } + + for (y1 = 0; y1 <= (int)(cipher_descriptor[x].block_length*2); y1++){ + for (z = 0; z < y1; z++) { + plaintext[z] = (unsigned char)(z & 255); + } + len = sizeof(tag); + if ((err = gcm_memory(x, key, kl, plaintext, y1, plaintext, y1, plaintext, y1, plaintext, tag, &len, GCM_ENCRYPT)) != CRYPT_OK) { + printf("Error GCM'ing: %s\n", error_to_string(err)); + exit(EXIT_FAILURE); + } + fprintf(out, "%3d: ", y1); + for (z = 0; z < y1; z++) { + fprintf(out, "%02X", plaintext[z]); + } + fprintf(out, ", "); + for (z = 0; z <(int)len; z++) { + fprintf(out, "%02X", tag[z]); + } + fprintf(out, "\n"); + + /* forward the key */ + for (z = 0; z < kl; z++) { + key[z] = tag[z % len]; + } + } + fprintf(out, "\n"); + } + fclose(out); +} + void base64_gen(void) { FILE *out; @@ -530,6 +651,8 @@ int main(void) printf("Generating PMAC vectors..."); fflush(stdout); pmac_gen(); printf("done\n"); printf("Generating EAX vectors..."); fflush(stdout); eax_gen(); printf("done\n"); printf("Generating OCB vectors..."); fflush(stdout); ocb_gen(); printf("done\n"); + printf("Generating CCM vectors..."); fflush(stdout); ccm_gen(); printf("done\n"); + printf("Generating GCM vectors..."); fflush(stdout); gcm_gen(); printf("done\n"); printf("Generating BASE64 vectors..."); fflush(stdout); base64_gen(); printf("done\n"); return 0; } diff --git a/doc/crypt.pdf b/doc/crypt.pdf index 760d734cb9ab9411b2b9d256657451c030f92fe9..b687065036831b52adf02da8c2471fdbb59edc22 100644 GIT binary patch delta 364740 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

f%qBXN#|OH&QGR~*bW2K^er~CwR&6;&^+D; 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 delta 313118 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 %1G+G6@PUV?C;CWjCgx{II}7sFIGydPn+ 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%0D#Vg# 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 z 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ℜ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≶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�tq*H9^elao66x23<)4EWsT?-=zRda6$QH{i`+C zKm<^%6o44GDom2qm;X_l&&|vo?fO0?-2Ri($+4#0{zdu84K|}WK&(t-^C%kfiGt-ANGgTtG$+vW=`o!5=lh1 zehT-M&1K%qV-~b84=ZoE(C$&kOV{_`Zy-x){Y=zyh$AY91 zd5s{g(ST4gHP3|jJSSG`k2<2;&rIW_o*`Bx*ro029$(?OtLOpG+IS_y4-Nyhu&ca+ z^WVb%U?MVDIRD>1@IP`SHeR;>7Nzj~U-E9A|DAV3gsOe5!UDbl>on#J77PsDQqX0} z-}-y(ll>Z$`^;{%norgQGQNqHhT%pgmAv+18^zZo*8iZCO5(WddD^et(!UFC)N@SVWB!*r0GQw{Z0htmJdUvo9 zERKiDAvW~L96dw>tR148$&3s*D&_tClh-P27}ddoO#}NOw2`2eIifHn{IKGz*-&6&Q@))!+pUI_@N`%!RBz@WqMRCj;Jbv z2GJz=xD}_|VrG$0c|yPp`G`FH(?_!G)4h-r5>eR94{25y&SH;MVh5@oDdT=HI4`l| zn_P>ixfHG`Y8l=qXmyA~+@BL;M4Yo*LhoKv3n!La0<9ukyO!EO6I&6ZD#^00Vk>S8 z<)gV$Y&#u~6=JED*_t?NI1i5syhycnGe(EGSx?$y#GjLB>sl@b&zc-B#??2kG!NtH z18Up|%Kv{q?*AI0bNmlM7VrOMg3gFKDVuMHaWQEsjp5bwjz4dMi!p4U{8_D#DAfOkxY}mNuBEutf=j9h; zrG!<-%W@%6a>;uGqB_dL$#=i5hdA{GLSOXQ?WXTA=KLlByRc}vT}Ev{6~iBt`lBz) z;wIR%eV=Bgzht4s6!>7}RB~1(%JVvZ-kMvJWFiIAg&Zby%Z2`nQ^_@V@X3$D_ zuW0t5P@3PThk(JSdFT2*yiRieFD=5GC-8ml4F&kQvlkB($sEQOqq!6MXo?_K<^2PE zvAeG`rj)!m>iJ;Hd46)`yRqdZ($id;i+5U_i+rffE5+bmI~gp=iM#0jF&F=4!si0? z;m&#f`*t!2MB~dDeg09HFvnUvd2jaCaWV*^L4dPLn4VD8jVK8>TZ0kF4AObj5P;aA z8#L>2e98i9nj6?$WAv&ueV56at=+ovUlFM9pfUa-l-NCWT2~?7FMA_#w)EsUE=&6r~s~z zy<0dtQ2>bcK!cSaXBRbo*M~YT9Gl|m71xtX&TSsdBAm9glDOlfC^>_@fmH_b4l?O zU=F@dBu7zpQWnd_S!CN5dBcG%?`Gt;6729f2%$u#N|D32@{$53p$B6Sa*rX0I~Lxd zr)5w`G&a*-KH71z>K8yoiK;cyET-9nTki)9cNyIFSg5H46W{DXZ)J(b-JB6Mc`q+lG>1kiN2q(8u94mn$9`p#B)G~n8$F)Go6u2$=lN)n@KS+>@-4z#x zXHhC?#LD=3bd9?hIxMz3?;(8tC|jl)B!~ckzDjyGZJ1TjhPODwo|YAfL&DyCahe5e zhr15ll!mn^Q7TnhE4k5Hs#i9zP|*--dZxu(R1gCv{tks^t3ae2z@;wjZI?s5h;qu( zYawR|ZYP`&R%)TY@N}SPEqs`AEEe>x(E1GizQc-wm8YU{rg{#Dlm*-K8PZsVXFHC9dHpkVQX(ZW{sYs97J1K((EpQ5A8hn~Rvkb7{qyL^{$EC!E7( za8(yi29m@xR0$-Zh*avJOE-8tkR|`F6@sgScygkk%nzKVh!v=it?~V3=P{SL{s@q{ zASaGJFyw25#Ja6_Y>lSE{e$ZIX_@>JjmdeTLx?zzC0VE^@B5(#i61S`>$V2ajU;%N zuUlV~_&BwUQduQo6A$KN*TONV*e({O04^WmCdvL!buOi}O9|B6NOk;DCwh`w%HIP` zfxfaz-@+m|Q&)w_@_a*~CkC(@p1dY=j`1b+euoH)c)WQ*&jLQ3u^a4CcswMUqeImp zyUvY&iY(;dqT~s1;B++nx!P(#*n~@yAe_j*R7~&kJk&gZ4S)FTHMTf3#bccbN$ckX z43gV~+B1*SBK6NMBx?-#U_EzcQ!&<1ICrR@7j7w(Vx(J88M`H?aBD=UPi0`D>>gqW z)-G}g3UbQk{@bK|DA!%ER(ro1fA{GqsJ|{#DHlHZx@af~cL&`PI^mN6&ls_hQ5$bw zC!Ug%A&E8=V=nj8JD$c`^s^?%7$SHVMC|Jh34J9b^l|Olq+*G`e}?mKSG31~e4!!4 zry~_-*?#4E!|rhNIz1{HZE=V;ivKmn@(_`a5My*qN#uB4Yxia)672a?65Gv}j&eIz z3o)|4&BBFz0klUm-;BluQXiub3oqLwud^919^8E)&IpZE?5uB#h_@Ktvmu4-v$J-_ z$J<}{;FZ$EbGu+y+hjXCLk4_fU+jqKxvW-GlACj` zQuUJqV;^PCT0N0n&x3CsI~3ch`l-m9n&LhhV7()FrTvb%umJ49b|HmtT`8j_ezanr zN+Q$0+-$WnXL+3fRCJ2ky7lYl$(i-217=j?4eL)+FqGc^5M+ddBz>0_M4ecl_}r@G z1IWLi6_|;+y6e?ofAb@47lQM4-AT{(BJb z6R0M?{7;RH*EeP|G{jAKqidE@Cx^ts>}uagqn_-wZVT}N$n>KMKHoecN62HL;nM7r zK_y0l+HJGgQbp{rXj+q76YEAC zDG{Nx-OnGty{G+i5QeiZ{ke+>94hLrd>Oq0>@8TmY-PPgKvgKF5Dx!nsYU8q+*^~g z26n(0w=IsB0D0CI{$3sFA6`43pGev*_@)160Kxm8Se}iG>%S=qy#HYu{f~(!Zz35L z=ui_ti{hfFw(^yDJ#FG`woy{afr!2XgyB-XxjR;~1?w+C7T*CH;5DH3?*Jm8!Diah z84rMPm7wOP#ocgg*rb51IHP~Zm0(zZxaiKN>YHOUpHKyRiN3Crf#H((2daMpxq5D~ z#g*0p`Q?z+@G-}DMb@$p^X$wY=$45pIhv00Xb7XjxZ>ZA6|LYk?B%m?w-0=Abjyqv zBvn{6ScLYpN$j^5=tmm;@mf8=gjsWFWcNPrL;ZIP9WDn0!>d)(3`DCoe0ygi(?#4J7lq#{9R%9ZGeDR_>Qm|K%WO_}t;~r!b}!dJZMHeXERK8U za6OBD8V0P5lWLg8y=mX>NR;mO%nuB79S=O;0yb{-n3Zizo`A7*gtpJ!+w+x!qsHb< zEUUlW88?kqd7=M0pHHdY+uq;KJ*{e)_5^yMQ8AM<0_Q{Bw~Nrw!XgtqR)zQ!{=Otz z+{`p1V4n1<-~ZqS5N`DXF>S(Z-DV_-wEr^j#29YCx{n-eRlv%jZ#dGPCaLADZiWX;y<;i7a6SUYGB)P2FIH)IQmsIq(W& z)Y(3q+a#@M0osc3k9B{r`fR%;Wdc%TN*INJ_<8Hr#JjWBC^nBf zyU7F*jKoWU_CgVV1+90w!_#c_@_&US*f_gApVmY&yY-5V^Su1BANMu*Bs@}KRL}O0 ziXZs?8=J03s3Pmp3{r|mBZ$J;mvAaVU@9^oNH;%sLoVBv_$Pat_R=iX+a~ zcyBEnP9V+lA4AbROQC1Hjuyb2UV`tWv9z_xLXc$^0c{;n3olC(H_j1$W`FtT z5(;kmYz+AY85E=g;DrYx|4p9R#^lt}0UFW)kP$z5Xf)r^#CHfvRD#{eXLJe+Up=Nu z!Ms&OduTbKfFN}Nw2TEYEQ06;H6#b;1 z_i@jS-pe3uT>v?dn2Qn?GgQ_JrBd)f;rFm-js=X|q#LKmG!^kmgdvOu?9&9Q^yYzL zA#?R|ZYvl)WDYIw3x^TYS)mWOsmMc++aJO^Z&# z(=u(VVGNLvv=AVD0W+s|{H!u%rey2t@UAl&en=D-H6;cpi5t>QgZ3TA$1Hc%Q+jF?0U&md#5-udmxwX8!y90}@7@g zdI&jb@7)*Vr3b(R&j%&x0Vu)AKrMOzCSd&Ys0i84%XHOt(btcLhY;y`y~b!HR>ux_ zPOkse9^5z9FNg!Gl3>?oaX3uM+mA$#K_cg9BD%zXdo})(1LI~c%#>w1N8!k?mYSru zVq+yR=dS_lL)G&4uAVYkk~u-F-O6e$*k9N=n48r*Je5Jm4I3pD_r>D#U+9`YTk^nu!NqAEuS#q~O-++DK&Yv_ zfL-*l^|HeB@>lpN(#l2fP#l)2EWpm5yJti>laj4ejuG-()O$;WTBZ;3zq;MXR_ z5H#ieyie%D?if=CFH(q#YVS1INd_t;@Hw#GhbQj8D|e^_qtV|aa^&B0QVWI^-LUSm zyJcQ;X!fWjp2Fqy8R!|?21vqChx4KQS-s!ZcnqLVn=O|9c|k4njZx#wuVs`)%w zW?WA;?G)mY@4*u(iV_ex|DByp2-*3NQkqphR?sw)_C&c_pPHmwx)g_vS&tXJU5#IO z=oj@jFn3kaT~UnJJLZGTIAqlfz{eC@XN8)j1p(DB;| zpGQnaq;oowtKPP`*s+kCp)Yoe=FFZ6$UV1|8?+ z#^4GyYv8VuDSTkZoOsSy3B$eiMS>f{4+JmydwM_3sw)+~MpBa=Uwy|?=-{7HZx z;+(F=@d;~FfBMx>elc9~WXnAb&7|Nv#Bpc^*J1n$a%v~?elp0}0xqQp198f3e`Sb- zuBc|5vDXpER+g&xsx5$FG)!+0Xd;0zz6hdX2`sB>mX%TFn0vZ4sX@uw7iHII!040A zHg!NooXA@$3k|W{EEc(~rwNm@@$kvuD6yu=-aqZeMRsR}U(7mVkw5os#2*UQ5I)}) z42{dF=<5@u)Fx}57@zR<0dGj-F4117KmeZ~o;>-|=E{%Bl0)VX9aC$~jmM#gp6$WA zKg>0*qbYwKMtgvM?vgQJxtQ#yLGR4a`e{GeJt|q9Gq(>YYD*m;ZQK+Y8swW+z$v4p zHP@%3>HAKf5!&Etlygf$wG?X zqAcnI!JPPpY81eNK5vtBA2x}aPKibV4Q8z~Vj53Ti&+ZhzIYJ^+0J79Uf1ObZ>eNNmqR(O0EM`IRGWyGzYr%Tk+B5SojT>KTiCyqZ2KB=za;7hy{^FAjO0Y4 zKZ+kDC2;8rhq{wen=*m-H5*{TMp)s(!Is4z9>q_8E~06ph<=%puOUsxZ=ce+QMU}y zf~wUYkk5~f3mY${k+-2!n12IBa(|Qr<8Rgpt{{^-jkTS82MXR&k7aTF1K(I2_%Rb0 z`UGR3-bsq9&ncD@KT2D)ZubuMJ{mk6k5p(kN}OI(aH;?gJxx?Ve@cimwN1-Nhttm?j@4;%|dr88{vp-lpnjoohkKlTdfypir9tJ zUg?wk`Svq3+#jH+m%M}p@aa45SRU7HSnBX6W)00zwV93Uu6SuHV~F89gs};=Uk75a zYA$kGtVOCvh}*nuj_?oYC2xt~YEz>O6_|(ct=ak{Dq#pgn&sO=@rs%<8ZUUBWWlp;a6@@uycS_QMz!$M+Qx(GOaY`6LiI4O|Cf&WKPx-z z?5rH18)AS2h}#U{2{2dH0@a%VLLn4mK|JOFGTH2gn%eGZGxXKaN7f!BkfhOA3P_e%@FjOgqvrE9TuU3>Fljr*l6*)2(AWcW7yX*uOT#w8cr#lrZZoWhKL9 z85@Cys{1DUIpA?&cu-Mhn_00Y^yE>A3zc8VkkE(0jL*c--2(~q@+4WW6tjhR8ua!8 zM`Pa;;1ocaa)X-9`R3vFFRMyKWdFrKs60TqX}f%cxmW6)8#T3$N4!Zg*2lr7X0+I0 z8FH;`U^%b38X@G_bX~o%VX?n=)5}4IHvfV&B}o<4Q%ux6HH2m*0w!weM+#cc(AZbna3{GaF}I*ZuqLif zZ3>WFa@Ss?*5OzV`2JwM5FrnVy4EUzYk2(AXe&TC>3#z^F!wOqjrdyPup8od(i>KU z4AHhyZMo*y)gYfjcrTw)24|>l!*=R}Q+Z1H{dctFj=Lc|ajs#~gSZTgc^=zmtDja0 zW&S{{k0}&HB((e1H|))6d2uJF>?~X;Ovb9}9-Sw7W*%o+cjJug?J%H^*IPZgm8IktHQCyH16B)t@SMgu&SaZY=x#{RFW=Mc3lTLhEbues9J=bQ=*T3 zQRs*jr;dyC*&-mKVhGM{xbM`!4^@ek%uP|(@6YVg8Bj?A2xJ-VmM75dOOWO@yFfy~ z@3IZec&i(}f>apu5mX^K{|{T|6x~VKt@+rt?T(#vY}>YN|6{9T+qP|VY}>Yz>6ta( zoLTFfx~hv>wW}`P+V$@J?B63^&?ktXD})xb1WIewL^8R3E1C-;B_T$U1Qw~JMJgQB zpY@(f8Q@*%Si8#uo(nV^f~IgRK`0S3IMBaf-SE-VeJ2SOiH-6^)SF4S9T=z4^cZzczD_3#KT#mZp9w$DdXE=33Tl zOi+C7y>psnGPL>FPM-3|xf8-}#ys1*npYT+Fwu#k8L84Nx_Wdu%cHBlzBCJ{cXE;> z1e&*K*XT?RY8VT1vXqCa$Wv}U5da{SwyD)4&D!YRA?{+WVcOnp{D%DJW|&r#@Y?W( z6pklQO;U05AJr`%!uGu6_$q~Rc0It_tlw()rm7tDZK8vdxQdQ?GfeUE!iETv2szrD4; zs<^TQ28yVv8nai+A(avi>e6TLHXqwfWGjm9FVkcH^6^LjMOaPQ3#MCp@1(6$VgrG{ zzz5?XVDT&yl zg`Bke?Bx5XL#dxR)Ih<5o)p^q!|n9=_YDhrhXz*nS-B5+naFql84fJ7A?B5twDj+) zFmms3xTrC_*@bdQ9@FBhCya+*)+4N!36TYnRM$Qy3NWC~V4VD#*|UJl{4K9lvt%Ao z@P$QO6RdpVeySd?5Z4^)!&Z$E9O5CXWyqP(BwER{FWO~J5;TbRlt1|)C`d|)8X%FGvV8i@{I;OW zzaoKpS;d2pG*rV>D@*{}ya%$kzi=3KRT#IoMlLdN_dPAliHCtT5H`BPx=gO-8MG^l zm|yH}@1SHbh(uOQ8r!L0z3vezW={u*`UQ!L>Ba>)e18}A1!?*hv7)%x2C=M!5JgmR zY{$wRHW099Ux7f*p)ZN_;P~W~{}LWKO36|=5-6y%U_dl02si}H|K7dT_9u#Sjc=>4 z`1AwhnO8V`luFo=7+YR{Y7!W5{2dcB2X!eMA(b9iTN(#qiv6^L;G{u$yc*TTjKULe z8DQY}u0l1F>Y}X{I7^^Wu=uyKcC7?o_{|KKmS%ygD>4cQ>n5uau|W{2%L5(%^~=7( z@|X(Cy%M=jC;tMv^*&F*^%WH?PrhfDRZf*no`lRDKfd)B8B z%;+0f?mfW0JziV%#)iocwgBsyAxe=CakZbIT3jF}gQ$W-U@lp6yp`P(RB$I`r6mCk z(mtK4z*_?dz3@6XxacFFDyekjVGu$aDIL)&_>UokzR{;RLnRHVWFU&11;J)SC7AYx z;)oaj0G=M$v-)xCXR7J~h?L1?%I5#{wQIVtgqvZo5pe;_iQHcDDaZ^B?r%LkVr<$U z>|kX4-J_`!i`H#A?ZZJd9s6S$5@ORJH1vQaNy!Gde)OavqB#Y_I?Kxz&vD-{^=C8j zC&AFm>}qeb^CxQMKTI+EvoOS7f5{0V{r7SI*%oU;4 zAQ$zsg&aY_#(xZFwTPSSzDODhd(qwCwPfF>o8r3zizV|3SUYD&*{MfME(Rz)dm6fOG$!o2^brt9&tf9iLwH~ z1A;S~l;7^E11^CQML8SmA4h59(+JzLfK4;nwPVZf*B>Y<$KK>Q6_h@DuC$B{$JZ4f*c!$*2 z6$?B>L!1Sp_+pWYO~ub7(~xAKBB2S|m)%$#9KEb+R{V>xr0F8gLmL@zHT4-VXAYSG zuCC4WO&lFfDI_@%?eMK)IgEte|8_l<~3p??H~sT>-B9dT(DSV#&m&MXX< zL!Qman-cc?wpQfnANJj~7W!#}^y@7C$g$Crv+SQG+ILN+=kApLTa z9frK>4c*&Bi?S3K@>VakofngR1gzDD-987_TM2>&MU8_^l~~$0&{D#2Xl}hD+n$7C zqj<3hdNOn`9@!V7NhC4STz<#KH6Z1R*~X0)W_xJz(7IQ+mI*OaD@`B(nzb3X@3fJ5 zG%hO&;SCi_)uksoC!3vFLDtdQzeT)elESqnDlykS>jN593xMrvbfQ@}`)Z&l+Pj&b zrD}A={ra>3PleZ9S8MVxc1vwyMq{OsJ6L+04>%LAe)4UKa#?K3kL}p2+O9S=P2d{w zuDi93lk^!U4&|Kog*0P8t1^~Tl~n1AGJViqp}f-V*5zglpSPpqPcZ9IN(1D% zDbO~CHst1f&MTgfBe$nBMTn#fxt!9Nz8`m@OC}h;I>{1~+ac#^f<;jhnkIbvhai!I zoQiEPW=egKp2i?r2-C$|ei-~No6y}}|2kmZ@5;5$Sl+uNw`T(odLJ0B`Qk~HkZM%h zJEg}RnW`5GygQ_uNVD*b$Sq{3;kihvD_8@3&t4c4`*Hc<)_Jkj47K5fpNYe~^=olB z`0L~N@N-RhSa}$%>i6hKX7r<2DD)by8)Ixkj1J|J9h*I%69(M=FX$QBrQ@#G`6AVn zXvUztc#Mov3{EC8cUl=|yP!J>6p$A!LjeI;X_3+l@tUi@FN^_Lqh;I2iaP?Ga zyFizh->2hDy>$msdxs`}7A@R}XOJ-0dk<(lJY(kal0cs?G+Bt`I|{AmK$ou%!fE_4 z6pQ@`Zxcxx)_hG1>v=7nDZW^_Gq;>M!u9?ig`H9H&g23>+Y)P9I{>~th^{zMIcw0a z-XIE8O!W4_Q;2V>ni2`?J(nR@uD+HZP*C3;Aio&cKA$rm_*a%JXou?r^ptX{)}2p; zjDt?NH9)fVD%6Y+T*kjlOQnWRL`BK86J90xj9nrlQ|-!@GYw>8F2N|*{jEt#OB&b1K0@{%2uT_zrR?42eL>l+-+fxL z+8$kpGPSOaBI>vJWe-DGUon7Np5-5UB3HA4gYs2#1GQE92>j7w|vm{=SZ~ z4jT(2Yicqzs4ze^>NmmwBa+Am?{G@KW>;+Xs%bcF0Gi+UF_<8l1ijA>1g=a#3D((E zW^g2ys^k@&P+;(GYsoe5q~bENcA!;er1n zE@fh6N-d-T6;9>%1hogd%{;nlt@i{qhvJ^b2bzAr5wowssIB>~$NMPP>w0f9iBjkP z=-t-o4IxwqXnz~tUDIT_ydBJsU+rUfAkO0UrF{4#w<-sM-T(t9r3wdwio;+_f&QHQ zfLGBbr|vL=;(>56rhYMliU6jxHRCqMkmd9s-;hQ08em0Sc1A%wZ`bv_>%{TAF`|I{ z_AEGAqFptME?xb6D{8H*M5I!9w7?)}J4M~pSJX$f#^?ll26%_bW z_(~r3KPsar?aQcbEYXz<+B&+S7-j>dl&sV&=%uV9E8m7WLVdlT2mu~?;ngSDzo3n8 zr|K{}B0@M#KvL_`DsT&G74g-_QFN z3WC*mex4uIrq1Ypy1Y$BwF<`Cwo}TCD^(f|u)@7#=De>-Qj-@t#)|5?>LF;+Sc~Fy zKi{WlX_@WMIw9*HCjp8^*{cbSi)Tq()n~pqL6b9Cw_lHFEfg(+lnXzj^PTu1-=Jp%XgL&{0}DSFXl!86Ogu8` zJKFDpTF53!@E3dCpS%>Ox)e%^(7?;g+$UWZwr08=P|aMa(Etn-a-e3~A|R7_;Y-}7 zU~bd4I6AbQR7i%FHmcR$wFho?qc#Oq zbRPOwBwzKKo1$#WfyzY72F^G;Iq!msRsr0;H!-b?DS3PNC@JYm3OeH-ku>mSG@65m zz{bPHQZO1djQ}3JKb6OonqTg52$TkB!NAn`o-TSGB4p-iPU z>t@efM3CQO0-(IT?_hT72iHk!<{GU}rBrMj%+T(gnlhbc?YB9y%7aHkU~l zG^ZWAcWs;;^cDqc;qHn5_-uTVPvKmym8)8mQdPlhBpWi z2kSoZW#o+m^8r~SFVU!^YYN)Gcx>f6`qI)tX2BC z?*X8)j0CM;;Qa%1q|m9BdPou&ZK7W03lu>rw3OR!?)RF_J(I-1z&KuL@cOWe7EOYM z)CI48L~Z~%nLxv7JS{^ufr9mx_M9awD(C4lOZm$=JvZ6mS+7v-MYy8HU5Ad1-Ipk_4^T9)O#^dS&kjT6K|xm1U};PDBN9+J3<$8q=B!kJCvzipOb%MA8E?35O3WS9-`|k^J*QaQDTdfm zX!|aWGW6Y7Au@t6AicmqN)z{bV{YBImaujKdcd@V%#*3@`Jv^eJMgsyAsPmu%mC5q zjU$_uXhl?{88k*aWEII-v@oI>JQY}#P2C43kUv3U;SxEiB=$4d=_fw-)Qq6NxFQ>M zdc{FSGTgOgJ9nWKM$7c>W3P#I#Kcjv$P3QfV~l(k1JazET2E?ox;#HvDg2~m1AUv@ zbHLHkT*XRz`rtHUK`m~9xKH~`Dgf!csb*UDlZf_{V<1HW5U9j1a6v@D-jCo#Vu)w3 z%w!vLsgq_-o7g?GTZ~=}I)1b(903dd>4Do`ZZPzVET_Zq)S#UQS_a(mY9jXu>ic%z`Aws z;Lh71o9oVeO@GsZ0onsgoF%{r<_y$)E@bNY42w2g_2FOLyzbr)GZ7;w;!j{^#25Hr zg!Y9_`#~0vff(yxh3Ns|__n+x;0xv&J`w!xHkxnOyL^A2YXzczrn0II5ROm=z=@Rf zta2xqJNkM&?Vs(Z%bD-{;{bc`ZjbwkucxmI^IONauGfX(C~5u$hsomr&T{iX{0Fo; z1V+PSZ}veP$RNz%S)+X|o*IGAAoQP663)PUYn?s`LLqj9e3)w|KPYr(-6~+H)=n3Z z0BgD6gGA(BclxdQI?b|A&v9KAnKp`?xb8^}UXWMjump{U%MnHhVnD{Zkvv?GhiLWo zwORlJYAh2i6N-B0AxU|xF{`WZV2k5CCL6XnI^Hgx!&77)6KpNg=K@Faj_vEI8-qTtYg~M*p9}i5?nX zdo}|9fWr~t1;3RCF){Ml{N1=|CPTytN~!|g&V4F?$Y@D)TSRc&l*n&_Z>U(_O*!)% zLiEjyML9^m=fk&33yVln@~Gk3gB-k#zcsI0OZUG|IBgx?$^d26Q-Vy>1u4@VTu>Y2 zH#b+U3hWN)xTDy9OpA*{B-{^NL=kq`kY@%P@*b9)ErCLvIBCh_ z1Bx!=4Rf?9Y5@pS58_9efQnhPYAh_fE0m0OqIT0m?xBRhrj!C0 ztXz@$P=|296>uD@I1oXpnt7L#<$)D6h<1Pl$Hi4c08lxaG&OiksM<#D_d4-kL=~{n!cR%hZ-H=iXkOZR|;vZDZQ9=2#e}W6N|! zSgh&58JmfIL0zt@!zY6feqQee9LU7EbX-2>uqJp*G+AtMp!HwUALCNt%Y3k z55`w3PM#x8c(lcG!HbyGWU|+1Jbg9L zsL4_Lg0&2j`{zj_#9nyrl~P*)*xl-KW2s#}Gm7)ahwAWtDRd9?vC(he5iVI4Z^n~J zzl9ERH13H_VHV_B{(R+rD03M*U?$6kKeC`k6Pp~hAp*ULq2a!mZtJX^v;bKD{Lq;| zyFI+pnTQp!j3l!1neEcE`=Fc4Lrljq48+|CFsBNUa%?NRk}vQy%IF9JTo$?*lCkai zDIVpJt>AcRPFL!mf^#Zar~QC-S^Gde4t(9fZvK)Gdr&QUeEF|tlPqAl1rzYDFuH-I z&8_hwB7utG;t+Uqk3x5`Ob!W_irx39xO_@L@BJ37Kz^lKgwtPfiN5U@i5mua={F}j zDs@{Tew?O5DF_o%WZ$+0MDJ#kEn<0S5&pZS2Tqgsa!oJfOh|>nQT#h%fxB5cQa9~V zjzjEiHpvo}j}+d&t9+!gUd+V(vX)QktJ%Sph(9mAlbI-n} zcm1v(wQAOr6T$?-C{%mw1giYUCUC83+{*m{E)>ACPp#tt#RX$w=3q?)1cISM$(Y)i zyI2shrsgw(QKaG}fFc2FrP3vUVgW=yp2~Yvre;ZsCF((dDQ2_IY9`B-OEbRN4`lv& zeE!OPcp7g_v}gIVd~5vA^{bte>!aw2w$7klyUCM+xB6w|1Z9 z1hcU>C}0A+-=twzg~j7npQhh&8~We((~(R>N^`<*?tcaizE00^>6~2Ngg>4ScXU2J z9vmNo<8NV2sy@6|q-0^fa1V}z#s??L&s=zozHy9ZLfR0&*f~p-{_?Fn=&r!c2@j{E zjbPT^>?fFuIZ#i`*V;B`1RDWn{49%NfjulCjjU*k93FQUPFBoswo4yr%#ueRzl-JQ zC8mK$aGbY4^-@&_;muwrD<{oPdp~{tavdeT0!+l)`-(ET-M^o0nblcr+rRH}EK6bi za-O-?e_v<($^oX1kaTwD|v7PJ}R#j{7iGWz>f zG3%|<()qV~tg=krk1BlORmSG8!Fapycq_Ip1hu>i{(d+F3w^)9SiPwL_ zRmK`_L3}ToIUrpuZzU{4@-LnTk#xy}l0}u%-(8VX zFTJbKk}a}E_%asq`lOS8UK#mXd*7+;+}Y3xv400-Lh7~QmsX525V0DRE+WB+&)V5* zvS}n@LS})4#LFSqV1x|7?5-PyHfUkIf!JpYjaUpsZvovZkR|vc!Fcuz>Q5c=i8T=Z z;7t2a54JomVzy*BP)&*i?{Vd*M94`!WJoeZ_igo8;Stl}u$mC|BaFjygh z-^%2msDOANnR`8O2gfpywmg_svLc}0P{N+N>cSC7mp}o19^3Sl`7Vsu#p825^Viq* z9Tu8`-KfD8h{AGz0@6qFTf?OC2`8Kdt$nzH@F2+H8S~b)swbF6lpWzGy>#KiQXQyQ)`zWCbqv6M>d9kpnu`S%sCWGj>RWVZouwZ<9PT=g!-f z({e>)EbuR06{u>~qaiG&dBW$0)1FKa6sk+2Ac7J4Y=Y%l?8-2y$xDSmm!v?DFlcr~ z{=A2OioK-y<#gxvd%;9W;X83Kkn0v2Bbgyfyu|q03KCKr<}*%BQ7b|Q z5Liv<+srX5&8JCH5%BXN@jzxZ9!&&(S@3}0@%Bh2f6dU7=I^8-_w|4%Y#|y^;crDJvIuKzpfdNE;=TrpkCSA z&K|jtP|8Hv)VT)LVrW&=gTaJr{~0fsiVOtzfk(rL>`sCpV~*-@Tl7(sqUX1D@0{3k zga|YzhMm*2oh+fNe3Ud1?~*keJ3v$E@rd(PkP0d9 zo-#H~i%sST$)X(}@AxQYwW5dqA_V{-`_1M57A z;=_s@8n9>;Lb;ELJ?9zn2~W_RP76igjVGT{*vBL$x5U9ILf}VZtbS*~`2%o~j8s>y zo!AZ1U?w(kOOlAXW{BBC;E5)j@IsfD+@KRcA+d$?Ej#A~H$CV1@9MV{emY0;HY6-a zr%Rtb1)oLH-FI^kL226X+Z(Pfl!}b9KrB7RKq$YR^8b#>=4MXe?clVZ*%AjRZqsTd zaRe}D>muJhM{V4{l)LF5&n4{CVG-%R`StorHVUmsfAZ_)CP#GBMWer;cW8PPVq(B;F!=hZN~S$HL26C64rV*Y0oh*wahn0vn=RFcV=@jTS`mh)3p5=eAzhHWna&kcRJ( z4y~x>gI>RG7h$9^<0&ra*h|6n!LZ1AN#r^n=BN3-1*)HKCe&D{`-iE1mCmO$VIsCf zZ=i?~QClrxpPgZhMgyYA_Y5mSbCnbqtP_PR{McB%)j7hour8(KT?)A#I&L;K(h zB&hl2uW3B`!98ErpT&w><#R&FQ)u0g9nlY`NQ4rY|3g`)s~U1D8;o}rYuc$zCne1+ zBUdw4H-F&C8d9s(@rpF_YZIxgBOPOLAUbSS=gde{q~cgG>;$ zGtuBKv1YTi5*NTaxz=6aKn*&SdvpW_KhLzVCfwFNS(xvFLjO!Jy?;AEXD_OHc;gfbx^A9V$g&CNNm8qMub~r1u9XN|@CBzt`KD{{z!wW@Gt( zP%l>I|1tRh)vjBqJ(Eh#2SDkFi3 z*$)OXa=5X<)a?)bdl(dGlb!@=v`UQt_U9<_fq-E@3P=LqLLAUflpSE;C6sEAN_a0w zJkg`Su{-7VfA#gLlcb8_`9)oMT2aHeFs);nOG}{U)AAF_@ZUg6tJ9KFTO{+WIa&v2 z<8;~CyYs5)E4&{|9nMA_X6P9=MS2idOPMSGhj;uBqKt{1`9It;R_4_HGf-4u=EOTR z@>H{IP)FdS*41oKabS=Iy;R~{&?Er#84Y`n!5rOE7oS0ul!Czr{gD=q1rPw?yxe92 z)bKQG>m`i|cZPxaI6bV*scDOJU-b=%ib0)ZwP}fQ5fvuMV7kH?^dE#{biq)W5tNIA zq%+H#nBsm|&w&<7)E_uY4e1iY@e(^Vw4sOmIQY}4oZh%T!6-tvdDsPF&k67+E~4Lm zIg9SWm2D0twZn1<`m=R@y)i`RjM*e}i zMZ*mMsZu9ufmQrC@KHjr`UD6t29E6ew5Cd5^4uJobY#hOS!Se$=0b0Y9DDjUts-JQ zq&f1D8#KDjh9@xu_1TdN8XF%b3LIysMIgCtLpxvy@PZDF*sZtPMvsOIXOKwI+J`U@ zKIBno>MKxkct|Ln>2$#xo6<_W2<}1>+5-=ScL&QHCYuw;VBM2Sl>|uZva@~|Ya@~- zC_AKxT?1!wI`XsK^+=cI)1gy>yLQQ#ti-7j9OGDt$6j7AO81wGI&+zrX(Gs z+q-xu=aM@E!KR{{lLj2iU;%Kdj$H^htb*OP<&VI=j3rsf)PVAw(rsNRZJN_%Xxeg{ zO<3Scxk=ZRdZZyjO5ph1Y&Uchj#-v>rzmeyvMY97aWx5VFIX;?)1ZkxYfPN|mn}Aa zgd%EMyCh1@L;VJqf!GYHF(#MmD*WTXKo&P6z}=9#NH{$)S^(fzFYs(cXyCCiz;bs= zaM9qC=d3d=iObQPEJ_P|JTss%UmT_RfS`1Lu=4@bmvjrbhXkQ?Ry0nVNMp88I4o9` zd76ux-7C*R+WoDiyr*|yaTv(vUM%X<#^^$`J!j|DrcztqA1^Da3!wN#%JlsF_$(|h zSeFI7iY})<1i&!5Wt;87N@o29i!ZoizF}84NnqBu*j`|#Qd?iSLt|aC>4;KpO3&T> zuqUwX??05ywi$Ln%%V5f6@#b<24zLm3*>7_v7sL;VCe=P#E`QuW1e|FIxU`nxIl<^ z4X!`3%lu7Gad5*;@XI=jq-bYfUJPX^I@t+knqOdBW|l&*ua0s?0y_vzhb^ znKf|g8tfZnZUT%@2?jHr+-D}kd-Z(QLTMbcS6vcMrd(gcX6;C_WN-dyTd-^oa4r0< z%YEen0!OFd*lku6nQD|aj@&RRLJW+ zY2jdc&Vc3XG=xy*7~FKlM+{u#l)re7?9~!TF1O6?=38#!IAcW|7d%w?R%=FQ&5V<4 z^mLl>%!8JbJn&pvWp%w0t54&E>JtsqzKwe-mTf~;t4?+J;M11*orIlVB|lzxYuBR@ z4@N0xCn8Dl%BZf(J_j~l8Es9!`?wz#)xFVJ0ss`A{aG|ROYC7glORWv(;B?0^#-f8 zjD_HDFq%Z}l|#^s`GWsw?=$CL7~Yb}8PhJ6rgFMV)wh0a3aj<3qMxn8VSoDG>Gk|c z;Ck#&?KE9DboqyHsoZOH`&I%2Tp%%8Erqp5G+H&uJrnF(i;5m9TerSfcY7d%#$X3V zz5tbot*tM$ib^=HeE8D=N0>NtQnfzBWqF2eZt6AU-=W`u`&RtaW0;RC@5rVh2SpeM zZs+`vqiRs<~lotC0eIS#ltIEj_F?d^N zl7u7&isk(5nLW52qj!YLk$YG!BaHSQZKT%_UiRgag-!hN-2mZbp0z>MNlfS4X?|8@c_2IAf}$W^ZvFc>x)lJC{bool2%{ zyiMZbrNchmCXbanC}0cC!dk-hL!b?;z4H-g10}tYdpW6UaL&3c11M7(T;_kMT}pF; zaSy%NRrtQ|e@)0TlzTD=!T}G_fe4LiDF%CDj=3uXwX`u+FV}S!Q`}SV0RXMg2o-VAx%P1m~~gOl-d##R0R$A8EkJ zWa12Et~ssFB;a^*?QLm%&D+d8mUF5(OLr@02zND_S_&=~n>eDevGQn~rLwp49TSk1 z>g1uvY{YirFtao@-iT?R)7$Cwv`wfIC^6{r9w52T;3S1+N}v0EcBRjt2k-&hJvaZ% zVGWcUoQxceEtCu_aJc?^nI@sy{=H1nMA3J1yg+2G>r`ILLljgN0vE+~?{ttE&@Pi%sc=(P z=h&-LC(-s*ET)WfdYs%twFZo%>;;dx>#_IhkcVm7J}lY288_>KIrq7S#R6>9zFMp{ z-YLF{&|Bpd1Ynb_^uRZmAo^e+g2#6p0uShn1Y1&99Jo)b&zEX7;wucPdZcVa7co74cMd8rjz8>t_tJKGT ziIw4PY?!&GR{g4CKHy*$P6LSOZkVChY8ioxdxuHG3H5atyQ^P3m1x^%SZSALu|^*g zrY_Zj6UCF@f(b6u6b=i=mcFXB$U>rvqfcWqdGz_L}{&*$M!_5n6XbRn| zB!TdiF@h46t()oDW&-Tcb*j+}VIGd}f-(Kw({5j6Hz-1qCm{idde{X?eKH$v)TBCh zYD>?$Fj~fpR1Inls*;&>{@CPrVtq_-a0u}V0az(*FWAXG(DQGu`c4(X4O$)Q{6xXc zVxE|)xy%~Q#iNeM1`^I{22>ft{&%xcmG7Ch6TFj_YK5J${eY>m$(7?y+YurGiiw7L z`wn5qP4NYbTLMh)Ijb&HiUL(AA$+S1j-MK2UX7Y)No@o+^^?RGrtmGI@C!7`K+cgy z)#b2t_l@u-zPxB*H2XYyUNSf&h=?J=+UO-8y%#|jLFnc(xyZh}*ldTKKpEZ;prClz z5fF*%#@0TyHvp5rCs{ozpK%Y-*_hltQyz6r8o3*Z5*~>BBuI|8zvT21%&thZKO$U2 z-h-i{tvwyMfpS=o(EGc=$zn+?|eur1KdYE0O~maqh# zFV~3tH?Nc^#At4#tH!}5iH&fUs@kUI@3i(RW+p8BN=BzrKGLe%D7XpiGqu7?8jS(* z;17!2tu`JsLQLSR!`7RvJ2C-Qlwn-I{^jQO4cIgFf+~%?>f}+Q1QLqz9W#FHYcvjR z1{sIe(1Z!1A;=+P(g%*g5-}o%EOb%Yzc^bI*j!57R1o$&B5@X;V78n}icQ9G_li2i zojQ@`?(KX2Mn-MV4bej>|_P-2+ABl`|$b3dI1BmJzANfm^CQxVbBrDjk*!);}EFGCGX-a|=TeUfps)`{##= z$`Na7s7@|hOc6FVtX6N7}wKYlT)UYW@Y*J2I-yI0hH+q zx5_Eh8Vu=1QUqabuxo065;K4-+_2`4GT$NXJMDw^C|d{#9&O8g3DewX8l&_r@q-%z zxb31&3w~@xut?f43XqFYhRK_aaEe!!QWlvjZ zf@yUhjGKs63>_&udczcF)238h3}cs|tA&F(As;GMOl%S@Np8JrY>-F#^W5q=E^&qh z`qAjvJ*d<_oTUbUh9>iB&1n+!ggf#OmDm_XXudI3!^ic(YD{Tv{|Pv`(d)~NN^RuN z?&^S&&(IT&HJ!1RsOjJDd*9=YcQHid>g^_tI^z~6*5%boU0YltktawVvK7;Ee9aHo zB`-;(=Cc4k1^orZT?foD(F@suSXTQ3iz`!W#HBzcq5cCPIMs}V?~%<4$5zZZOLMV_ zcX{E8&&zg0X!q&9Vj3S>X>~=y3u=-)h*aE~$eae!;>3U#Rz0Kq;S?`tmuxo`$w;Jm_7MhdxIF7!{!#4x2x{X4KQAYR zjLvl2VPPWkuC4X+d$HnfpXchWl`~+*N)mA9LDp2`CvFHP4CkS1;JFdIU?_1zKSN>j z&WtR7Y-Z)m<|-?B{7LJ}u%{nNzW|$zWxa27U z;{XZMQFb!6*a+53Fn>^PtB?p;0m`~lLJdO%OonN6Tw!l_ud|}q%^!7l(KZiyt>&!b zBLxN6YWS(Vrr{Tpdi<-E#o7Jk;VC(9TEQq^!@TpfgIpHm$eg6gW{{KFA!lGXNzqw5 zh*KLKT1G$Ew0SI08DV0{eCsojScI6&T={N^JbFMx5KpSCm!3n@E;8u0wrYAPVk`n@ zCi8j*z8k)ZXmWCr46ylKDtZ!K(!3S>sdlW{%V7-e%=2 zG~|RDpHv$Ihacmc2%#yJTa%=_=&8NF#{fS>`Up+wdX&>X8wdw=u%^qP2mLiV#t#svXe>uJ|kwT*VPXoX{@t3vVzGW`pf zJxl@Vu#R%ONZ9f`^XL&U5+m=+O)y+Vtnybb#}covRWz0NbAe9@M+VnFz(g@kqI&Zv z>J?$e>M0!Wl|?x6lLxalf<)GV_y4s6{T(w7=Z2@!LVY(11YT4Qq_RVs*&=04&4hy= zPb+?g>iiB`BOp&FvUa=ZxoY&p2NDffM&0Xdzat4+>S6zxgMLPU?UavVQKJ`jL&+W>BWAnMlcowN42N&;a(qEV=7)Ml0o}Jf*-d&xSr#*JcOr_ z15y0mJJ_zdpAUw#zamDdckZC5=>MUxvam7!S7kHxE(RDCgq0;#&>EQh-+phyZc_|p z%e4*`K;-4?o+|Fhq%JZ$nG%;F57SG;vMnc5G8X;n`%`VFVjNpa%^wP)ATR7v zdg))Yzv9hR2!@;ZTK}_CBiD!bjXU3u_Di#h(*BsTmLViw;{m@Q`7SfM5^SO&QFan?=Etgs!WD8Bu% zVea+!rLQdUdU`=MgB1mjnoMGZs8!TugnkI=$K3hEqAuz~eH)bl5L2I6TIkaM`!hg~ zCQFylwy#iKQ(gInM3}r_wQqfTXc&M={;U4v&R`-KEyKTL+gZC#GHqNY2ixl`+@PRy z?h~)R00Y=qn_hiq5cer2ls6^6=?0RdVIBGI6C> z{&f5zcMGun$sNMq*qYdzoi+2xbD+U{Yd1ubRzeir=?ZjU5I!?(u%E03m({BhL*t&YixlNcr=f43ULI21KM$B5MqknAwxWmo7J?tqXsA?D5U zQ6BD)9~_QW|Mbo(5GZ)*7!qHmZra%K!ax;Ho&L}Nql(>8C5m;GPB~B0m^0&~WV5yd zOX%;p$=UB2+>qofhsT6CDl3?L6J`_b9}XE%w`^gHhhb-Hr6A+CimVVfE<+Z+f!@~m(4(sITBL>_6 zthk{XMekHrM<)9arr4KDjjjxr;FQ=9jIQ=Vptk?IXV$y6n7M)VC*wBwIk#j1Yf+^# zxUM0Fxu5DO9I?Uyj<7V3aBl6+6{1hT2rp~kbS}nHfXnVOHSXsgH>ea_Y_kb!0@F=Y z7eFt3lbnO^jdgk`9??$*-5AkH_;q`e?P#y$| zIJlbx5@7|g2__}j!0MT3A-+bsMMu1ncTKN;#onJqa%JbP+r3rvXhkKv>>W?q|G((^ z>VT@2u5aSdDc#+D;Lu%yNQZzlNK2;(9FUN1ICOUk(g@O>5+dClN?O3T!F%s>pZ9&g zKMw3zvu4e2{btRc*?VRNc`f`Nv8o1TZ|{2_b2(QRBQPp8lsdi13_L1=f~lO+k40k8 zQ;-$(9jD%>Ie)>}e=nc$3Rr5i^Re<2hj>l(99SUy@&2oiiW+<}PH(`wdEo@(t`iDQ z&c3B+RR$=^>-!G1PJtDX+c0 zx0IWuldntdO9=~2*XS^AeaF!U83jte2GC)MepLn)AnQ`}W#^H+7F_hhcY749%KNmY z7b%d|#{)|-N^gUWI5AZZ?}=+r!0pAzm%hHYW!zMZz+6@A+a$^qD`vns2LOU z2qdVY@Y5k|*Wc>Y0zr6&q7Xg+St}J;qP+xQGROrEH~MB$_4s_-v~4gsUtKdxVjk| z1b6R3!|JkOmbTbiflsC-hpCqVMtEOYtjZ?La-Q$xmZdN%$;u5kZJzhi)V0$*pEcoy z$NA~(yk|_!r4Tw=71D@^%_2Ji_W=z_ZD9*CBqXkx1$Qj;#ePyv)*w)aV*yS4#@Y7Ygs!#L=e6^qijjlA^N?v0TzKzAljQ6G($3$f+yJwum=5TdoYV zY`NnpN5PK*1~d&g9O8JUK-jdM(}@MglR(X{UAHRkXt`91I@t5YCg{A(`@(c=FMM#D z(neet!y;T(Wo#9(eGd@`N$aTR6n=v2;1$2m9O7TbiRo8D8y|Hq*=Q%z&II6tXF5PO z&&&D}38J(#<}Rn}-h^vXAQSXRIODSgf<53{`@bZUo9E~l!Reqo(^qOK)^Isipb*Al znqPdm1}Rv7_*gP1p=`jgUu{=oY}~E{&l<<7r8gjE+91L~Op|Bb{X9u8^XlS6 zEIxisY{au77n)KoPcW~f+G(Z(W^Gkv0F{?DzrOjIQdLca^?(c@qjTVZ8Jjo6_THZ(MI`ObgdNU3V#D$k9>t zP%uwf_m`nZ8@@@u)-|vy7j|!(elcD88gl8p#nL%mu<@2`sL_QFeD|zlxZFwei}@t6 z?8t?|QSL5G0Aqd6WrjM0aPoEms6(690wB5y4rrP`OZQP@nS zqrybJW|Zw%)}PJbj;{*m)oU%e&b8q>mpl9&FOhbTE6sxSnO5~s@b(h~K4|6|>S*=*#4a&UYCNvG4@U#Afru}M zhpE>n#A!W|iJNpmHrIrTHG`?fnK-BAp+C?M)CLBWanC-(eGl~AR)U&p?hY(1Pcpw*$P;5OIach*26gH?y2AwDEw`n{ zkxD;DXdt1%lC#4)xvq4$K8zcaQgpTalE(_ox-D8Iz6(;-Kf=c$ChCY>i_uZ36*H~g*`?(Mg{Y`u2WU0#tU&7JADKLP@8 z0)tpye6-$1Y{JBM%u1Tv*`-$aI4c^WAZ?EALriiwXH-wwCnDz*b7}cf%ht;*vr_yq zw0RaehunA2nbL!oSs_re)Tbk4LC*G#u9u~j)3w7=*}Lzv>IPMgx4_3jHTz^#WEyUY z)B@83vm+S}2fcV9*VBgsnSMc53PD})2pUzYlH!`g`ZdRI8j zaS-zn1(PL>7=DnItZ+R0m0AdL*^&0hg4S~;$qq0jzR-J4;6j`$^2ta1PKkHN#3AOl zsLiD0hRHRB|4Qu;6*8+CiRf*pvZb9DRb&o_NI2NWmH|Hy@$7RJmbz?8b2&~DVtLEs zYAbzpBj#dD{geK33=YvflDucRKkTEX)P(DPdr;7V2X2JdG04wM3}h(Fb1r+NnIAn> zEcN=~BJcVxz9PDd_7+7)2WX`PnE>-PvK&&vL2+dPZZpNH~p8FRwH% zXLU_<&JV)~+~t-ezn!|jy13js4EtGoVcklRr5v-eq|R3tqN5x>wROwl8yHi{5Mo6? zCT})oQz!PbEA?~Ys%Z!A4fMwwqQ_w5)wIzVf1!4vTOQ$$F8GYx!NqL;Qu6D_q^t~i z0%QJnC&$}rAD0X}ehvARdUTl=<8Bl?PGDQw>}sYm6LauJIdp z4H7#`iVv+~Ey7nN>&3ZIC6@kJg6pl&MDT9iyY8rdpx2k<{j1sVnGsY=?IyGpSGfpF z?Qraa-2(M8vkXyYt^4Qe3cKHHf|f{mOjt1g=r>9un}Y@9wMek%dqVCSjpuA!N?q{0 zeqYyjmerd4Nvc&m>NH!@f7tgJM)cplYc~j{?}<)*x4$5%>#xv{(I-do`tY%Kmk_h< z*s-06XMqLw2wC1^3v?(n`mVC#bA^DO6OLf4mwtqbAib6j2iO0a5z-9c&3`u8w5<>V8Q1p(^kv<8Lo_eG*mGcSEBF{XLu*;demw@FF-h+@{YyKYvHZKr zF1Y9p1W@-4%K|4Uw9s%St0^2QAQ$I%ak0ATtdM3CnyE}l(c!FnZC0PkI(^sl5&zMG z*o*_=*jSNr7geJh#*-y34(vIm=Y_8-Jal`#laMV0<$}qPkM@J&)I$<%;yv3d=}sTn z)@2F!mk0AG^j2EU+Wkz8vsdo$XscR472O#GUuTf5L+ z`BdkwuLF$2|NWD0-9Ge0*avKRHd&Um(BB0QvC z1%smpUZ|Ho0oX}_f;s^!aByUjD+n=lT-&>eK)7H+^e!w5B^Ny;b|0_H4G&7RBE1Dp}-hy-4kirs{?EcN-$RdWIuLS80iX0j$ z<|hBZ{0#~ZmY1RqsGqh{swLBqs=eg{mB(14h|jr;95i;tuo;@=D-!BGiyLh;I_=_g>56rY$v}zOLwYD9}Dyu+tH*~{rx^bz)9kC|d$-CrVvu5-1bznpd zOEaLSL1k)>D>&EBRnNM;`Vpq}El+yi5RqUke>kGkmE}0JK6w|eOh-fVg176`Lzzxl zSS17dtGd^@2%~&YQui`m#zLh8(WQ}AC4O*y+$I#I3!T8E0?1JJhO<=qq9 zk(bR3nO&zwSbJRNQC~IK59>GFT9Z%LeG-`V-+Ebu;~Mz}53Wj|TUv}Oh|Xn0pXShu z@e@&@+@xN9&ZEQ#cyFn?uEHCz6%Jc(BCV>=XkU~&yAqOqGK4TN zt%l3Y?CF!m7fC2J0V=|MwSk8WMQ`O$)48~;;;IEy__M2F84kqB(FiF$xF;iSC0L0l z3&%!4XKPMAW0k~k=quAV4!`IYY|Ls-c@w{i1%^CQe%p(DIq|`1R{vOq#Y;P4&O_)W zr(GuHQsfevcPVisDgwI(Bjgq3@k(a zEW9t1=u50z@zwB*vT1M`Gl}xmAy0kqxO^FRnuY&{K8WrDbgIiYCD77RYoS;)88;CL z3d=x@G>{S&4aoTT0U||oFiFQoj0ZJB`%$h^&*`QyE1xU%EtocmCWn8}ecAI-ceyE3 zB5FUs7Rl$0-NYn?7BL#QQtw+jcw7gapFX48aA3z!S7DxyU8u)-kk3%Wb?p#8n)!Hb z*!l@bHLY>w@#DZE9 zE6Rdfl-Q#;(7-Z}9Y#t(_vO;59v0f0o!~Kep@jcZ92PlWd?tRo#OxFYJ#i~|7i*kn z>f`x~jfqMfve6RcXJ`I#89kE2SPnzTE=IQfh25AmFH*Oaous|y+GltSnetFExeHZ9 z%EYvN`R}F|y|3e!+U*V{HIYgQJXw5532|2r-QJj@yL*+13i!YwSIK9qRk@@27(m6EeoQ7WU>O?~ z8kOr^?`8j9aZDgf{LY+o;?P09$VKnby5_TJ0tkQ4>RBoA@WC)q=lR;dY4p2tw( z6`z;Y{yOGg=sAfY!Gj8Kn-(ZGD>O4+9z@YwdW z>-a53@0$Lyd@Mh6W0Qz}Frk{8)C1Rs3V0Z6(F2LVZD~Z;WKKXyV%zNaIYpCz4=D`$ zs=|6F_hgi%l*v?lbksA9`?a|?I;?e+QGr$cUZgQcUKmkfG=5bT_yw_|uzO^*4ly=2 zy>3xSE><7CI<32&Blkte&QGAl3H*JW;GB zW*N?g&N9#ync4-~92o1hxzG`J6Ci+pW{5Z|iV7hfu)F)&W2vko@-ZN!8m?KHrmp<# z>2G-WEi|F(*P2*ciXcTkQ=OG>z>H8 zr!Le@)1+}iMW}ywj93(&G*9ItcCqI}UOUFyxXdo{j7p#hO1G(;wkS29{X&W!weNmz z=J1WN?8(Y1T-r(tDii9jnX*4EO`bc{9DYiwn1C-h@j`57GoK)X zh=t5YTYvg-p*ON`I07zH%(QiVjuNME64Wl#YZQ@KGB!bp!H}^9XNiee|GelRSa!B& zmQQ-_nF{3y6dy@Q!AN|D2Hi=Iu5>Cfc$C4Ti~8PX3~p%w@x-vYVB30@+` zD#H22v(xKx5`=Z;ef9*cO>+x&(9b{ha>!>Hs{J_UIm`4jVz2u~#QF#-OyI1}5GzWC zX7b%~+pPoVWol}br=RER-xf({=@y;FIXT&n{c>G##G#T_Zg0L^{5+!D(AqNLToOFA zl+(N2o|dvcnqqHbK7ex!sX+|jG_DWceby%1B_Wplb=qOE3MTJ;Wy+;x@VT~rKP$^G zHoE4`U5kzoq{V+@e3bHW^W%&-)vyl3py(gtOl}_?wQk2Xh<^<{twcwmL@N%gbH7bm zq?s|4c(o5@cZPW#jT0_7{G7$!EQPPIYGqjz5J@ESVwv?~qITZVcP%R6)Q%}pYr*=u zeu7Ra)4pfGz!SNOZx;~Hwg1@yD>~U z@AfpWChl}i3#GA9r{2bs1Wc)TG*uDre@oe=UcA+RYEJsy zGmz4BGA+6K`^S~SHPWUW23HR;^m*IFc)eVzX$GI^%|IZ9zehk8q!?W^lex}bu;zsV zLf84~-5xbcewq6Ex15!03pcvd2-%AQHUv{b9BTMO1wyIR!dBrPVb-R`yOWLI`P9V6 zAc2@~6$2cog2ULUzv87ImFrWa{fIAOz!Z1ai$2Bv`IV$o>B;(9?ivcA95n1jxRb<1 ztofu~aZiDu7CSZxsbgQ7ybY2r1txsKl2~y0-o#>!+VZWEjA-iP#sgUH zl#aRdf)_g+j$8Z}EFy4KQnBdf@@l8m$8%7ut!9QK%{Dbv*X|IXEG_hr3Lg9vd8;-* zE1`B=?zB8l{hvx!$Ok-p?oiXYsz#&XC{n6za5+AGgg$@y^y);A2)yOgtM`m*xMfll zR1kwRXFgMzA?h7rGW>cvPziIjkK1uck(m4=J$C=xP~X=CF!dJs}Al|usuFwJBL6I~0Z zL}?BKg&L9T*+GqFl$Ku z_UP5i23Uv0dct%wE!pG6vHlfMf#PjscVo8C#cDD-}u(Y(J`4R7K~};@Y-smQShbW~lCP zKF5vMGHbPY`yy5hIu1fCM8~(HOMLZ3R{~%AJDc)kBtoL_7Z|>3nru*n2;?0CHpGg- z1x9Sdp?^qq%tkF;DNn`HU^d6+%?yEq=suIXrwT9DVQ>&7FqMNK4KYS zLmA(ag}pkNjbRYHO*=ns-8h+Pd{04#s+D-NQ3ZOc`s0A2RH}}KtMd{^@enOL9VF%* z12SE=-dFhsaE=&5k1jE5);`4OnyQ?p`Pm72E#JJL_$fQI@eY(uB$)kZuFM5hP9x8i zV>~ye4_tda1H6_h*~C2;c?OTaFwT==Ivg!)FyNWmgwBeeS<(`+??fR-Ur#F_)Soos zru2)S#V~QRoa@xiU`P%$b(MwZlK7|p?-q?9bE)YovQ54F`ts-SKBz{u* zg|(b`Wu%0-Eqy$VOQxXtno~|8E!TWF;fL>wjaH~#F7u~`Hm>D@%3|(UsId7LEG<0s z*l4nd;U7Eb;}$OmY7$qRD$j2>q=a#m&+u{wvZxdJ9Zf$leORty8jHSsZ;_{L=4QWI zQ>bhjpZ54*9X)!ZM0m8Yya$udaN=mQad~8(pz~er0?F(ryFoKrIZ7guQfH-pqR%K# zeJkpqb8lhKDmtSS8bq3lLay3B<&qqTyamk!=3*E3jcTA5xhjt++1v1Nit5M;AF5SG zB6@s|>%`CH8+8b`VtOiT%ZOF9lf1))1xbGmm#*b&lS5%I4f3L-3H$Qhq_RV~Ccu4L zSkTgmUlfiw`$mc4dM&Z;RTNo_9(=VUJs9gU`vy;#gdrLdofzV1?tE&;*$dVpVQHpbcI< ziUom}iLK>JXmtF6&q~ASH>}cnlrC?h52^ z6a7GwB^UR`BJWbw*CD47y<~TmdO@ukD15Fhje9?lVDyNNOZKZDNU;dT@>Gv>j5~ek zl*Y9-62k}2rsnYD!3#U>JpJ0P5eqBI?V(+)r_+Q?N&}g4>z>o2Pp_LVv(}2t!aGFN zoGq7|yd8MGt3;GiKLy)S$VFUP*xd{J*&S8sEBFEtGDs7?}@vxG;XNyhT7X1 zioQSwKYuPK4kqKjn0#bA&rG;Zr%tB& zP~DMTIg5xY{`*c+=85!=7e3dnSn64_mCp9w3 zhKP-$VE^^(uQtE)7=J4k1RRZwZ$L}caiVruE1iCVc+kjyg1S|U!a;1Vl?KfXBG0|{ zDkZ#2x>ce*olerzC&3EpZ@H8_E)4SOTmwFd&rH?HVqE66U7A(Q@T&bl_xk-9?`Y<| zn)ca>rP8MRsRuX<&TpT0xWk<^cZP6rj5M)#adAE{6d3+T@Lb{k^XN!wY3A^sr^LVK zrvh_u1z=z^WJ1{JJ|ZeSF!V1CVumid0uPGI*2$7@VpVl85p4{qH|N83zBv#cZ_{$u zLsD7KtAZ>X~=x3HDR$*yJgOBb}kkLK`=_eM>Bytp=hb+$W{!}myH z1j>~HY-htfF%g{cY9|_E=Xtx&a4R($yfZqShSc{VBa2%t+vm3D$KBUgMXk_@pw8XQ z-qlQ#Y%y`a>$6$trp1j_&h~EhlgOOVw;5wr?RjravLNfrMe4}UL`|ic|5jAs-s;sEORDC+D^fC_@;@Gke zYJyhwH#8dIk;+CR<;7*I+SZ@Y&3$Ug-->IU;F2gc0pd3juS4ZB5rdG4zB_#189Hzc zi>!?qwa*k#o`rB*kB9oFhVi!Q8A2TeLLxV8pz&qjrTUzUqt64CJ`ErKxZ?9;uBEhh z@VTw~V*HZma~lhNNCbRFQF8|L_d+n2y30cAZ*uiKoKsTockiubR;IhSp%?M}Rvxz3 zRvxtmmAZ>z#=M(F<0>WbaK$Z;zstm_?qy7rU5X}i1%!46crn!Y$mXTWmCoZJ5{7OJ zeJ+kdR1ri=V~{d^BO#^891-6?8RtnxCR85YU#DL!*i@D8oFXH-6d#_f%$`n}1=b(u zMjm2GSK*_tx2|I%9Z7;efTG+X^TG~wL|OKHi*(b%qZ4Im#HZ1{FtM?BSU6uBDh?+7PQPS88;zx z#|<{-MMfd;GBkQ>KympQOY%bDpXDsT@eD}=dycz~spC-^uIB#`a!woj{E{fg@ofOY zIFSUr`b;BnW8}pOp;Z5*0i5apF0;4{MQ6z)l-5@(k5yz##c1u zBSjf3lJVs{8sZ><^Voo6iXS|#U$>0K}C3=BuTWY1v81Ins!bGg5}JSR_n zc%xf=;CDz*&cuEUl~Wa0x{=y0W4$nYmEV{XNgGG;iE+E2HrcJ+@aTq{yL&TY#%6mQ%wcK zhjiW>_}cRsjRkLYOay7Ny#`_I-!O0#dZqO>P9Wfu6kX|~GX0JpP8g49&9gRtV-^iA z6Oddz@*xy0@4gmCtu~ybjDO9JLn|JaS~FMWL25_>xhmj|Umq^mDB`HeJc%AeWkS}9 zDCbY=?KNFFfu68Q*cnH}hNG$CX5I{7g%M3p=K2YGz5Bi=`ZQ5E0)@*m@hcqc)zNMi zHvV*iSMj6T`eTGMJ%=Y4Ize&D$U0jCpQ)1V>|0yRf?lwX+dXCK5r`bDX>0U@N>{m z8R(O@gEllN6J0q%q?AV~mI^I#S|GRmh$A4N8vRV~kR;w4lCRyayl*x<*?9INun^P1 z4Qnfx*G_hL*oHP*EPY0=!6OJXqb`J2G2gZOf|)W?Ky1v*d-a?NM*7`DM|c0t4CHqw-b>{mM9 z26f~jS{r&fFfk3xGP&&Nhg(^~I?%*fFvuf@8o*CP63kzqXz@Xu@p=w&XBOgEcIPPN za3VZ2yDR%f(mc~+>Zv%jW}34%)|gG-Vb6Ks_+#%A?9D`H!r?JhQ%t|bE;P&26wm6^ zM%jkGBWG>PMNURvX<;3I#2$m+YF%PsWQRG5)aOD&b)@ox6V zhm{;?qt)#k)b-0aOM8^6qRLnr`YzrnHs~Bc>6gp<0!qvSOTv;HYs~|#)rs{h8)z+S z8{>9NYUB(~iIkrXUOHB|e$g=SF0`2RCo`BPy^C+G#$sJ;4GC^ck!_swTJZ6uX1WC}4KCrPibr zbQcvxkT`iTBT^{fgoR2*xd%}m!9sx8a>Y>jGg-`3%GJteWk){JqqqAg4qR3~uZhVe zUJ{M`_}s^ph4by1Wk{&(P>gMtCDqY+GdnVww?yI0ORvaT9T%ZVkxX~<&R|ygYd07d_xESDR)_J$PFBya3sBQ zwmz-OvsuUYz(@HaZo~2ujS*$z!e31vjb&aId$(x|Z*C2)2gnRR_NkXwF`n%|tBo%B`k^IVrx`1d^AYN4t9Ju>KCz9K{qCwV*i9}O=1+M#1V6mS z+Atq&e~&_jX&pMeETj>G(ijA>8o4lSBshYSz{udmrCxtXQOuw`urKMo}KV1n^o?^ z`0Jd)m^Bs=kurAdYM1$CiF@Gp-%fvaXDYCZ31!$XMoD`{`Jshl8cfvl;sYLIEFJxK z$P4E$9x%U6f$EM; zrnwjvEivSlHqN6Y7l+qNOdK0zRxV2!ZzzwP^DlSE-Nj_L5Kfrci}FP`WDWJEoO2Jc z2HDYvc7=!M4&->h}6$!|DETnuQwT|u_#6C zZ}D<2I=pgzS0j&`BML42@*)Cnr9j;U$}q2-YvpAJ-%6jib~W_#Oir0(2Oa)8T{6=n zV$+%p3`sPq#yEPKY25zQt7#bzS9M4effuaaofK$1JLzHl) zJ>$lt;pF`uvH5*s@WqsNKAS4|j?S-nRR!2}`Mcwp0VTG3qQ6UtUOrA-Pbn1Sh2OwC9ymw;<)VTb+&4QErb#b zHza3%b01VtmR69>cbf=~Y;ll!dUuP1k2dJ=e~e-Oy>NN04<;gjj0vl>16jke3_wH(5O7n20f+`3Uht31 zz9AsEZV9r3IU0e8;e}zLMj)pLHBAV{AX@kbJ}iPrXLnSHur~wFeXb-=)+M{izSHkK_^zzt`$fS9!Bd0uM@}y z=$2`OJlwheh6}iJbAN~Z1#pKS7U%$|~&d9V;45AwfEgqa!wK3Ma9;LCUKd%oO5;rr^I2KS|d7q|zL0QS)b0Oh6{ z@T-ar$QqGPkmn&|0)hYOSUy28%*+I2i@*nD>Ix#j6a3@af0+hzc?Pn7xPR|qKEb~{ zd{+aM8%q~}6|eyt=JNdhrqCZR!&Kk>1q!^-gFz@lf1C@8yT1W&?I9J`{r(d7fDj1% zFS~^QwhI6iunS-Kf7u1pH7AfO%moUdA z3_-4J5Z-@K=azMH1m0JOPuc?8-Y;d1gtd%h(9pnzC0}dVb;Hs{A1>SlKd&~e`xk^ z@qeuRTO3&SOF9DN%KRU`{Y(7eZQXyB7Z#`ma)*V6f{1`n#*hfAK!EVTrV;@!2*LIf zK`_=oB?dyqLp9+2OD!+tPsYG_&Y$c2g0QkAkf+GQYHOP4e7t`s!pHlE3w(TkJkH1W zhj4rkZxaDI$X{|0A((zLh+6nhb^wtd)ba`bfrC%*Pj-Alf3o8f`b$puFF9d;SZy+h z`N^N$0IxqJ2fX>`Ki?lFL-_vW2Kg%_LjDSU5Xc`nBN_lJ4@Y+zVVl7xW@K*IN#(BA99ymt>CEUy3r{!=oV zR1hH|FEHTv7t(adynOuVK!XBp1j2||8HoG7jhsve>;W7p12lWJWgztjq!4)lLdM@K ze!%FDCVt-gOC0xku_EyD!*a_3Bmi&;9!v(Jb?tkA6V8o*VIswViS73uc<|TnQjilO zuK*A}n}PIyv1wgoff1jemYDxiB_tb^Wm;Nc-14}XQh0z~KhWr<=G^#*ku$N^Ztb2D8 z{kJ2zV9&~cH~=(v<$%#ZIniLIRe;C1%m2Vnc#jPM%&i=#1Ao(r00I2K32s<*CJ0@S z4=jWZ{O&6uw;z zCX#y&vE7#r6ZX9dNc})mtLl3n-dC2@cOX3&5CuqJYPBFzWC4D3J^>)VY7hm=-xc&8 zNFahfFaQ99=w3G!&{P9!N;ZI4fdip?7-b(QipVDfJl&Lo1pg8e68J+kAdoz`hzbZX ze=EYc4=)%nwf7)=L_T52KLq@X>;km_*@4hO4XddA<3xGnKiI;)6@e&`|B6a9IUp9; zbuCC9*4Y4PyC*Or1ZYq1!9jt51<-*X>{}g(;{P9k;%o0+0)|c9d*K1N+*+WX0@VO0 zARF+w_5eFjbO<8Q82+nx5a40t??hCH5a8JpI3tGDv;ctys0jd4FaTKlRvgr5h7^#S;}q?h<{5>aG6s|aL4Q4SQ%N{29z>~#`? z*pj=l&boB+p81q};1vo=rgW9`Bfl5VKw%<7b!h;dt?(*@zlK-!NIf4 z%CAw_L^r{KNiu@p*2f`m{AKuDB^TFRAu{_gq^y-Ut4s#=tKK%hqgUN=E)8;c*&?FF zDzEX#Nl)oA9676O)bQQ@SVHC=BbcBe460Njpw6nz&=CJzwn!tRbZkb%j+Ib>Q7e4L z-HwS+x?SpVzTN@n0eqIc32HbFsU;n$f{k`5>xH@A%lSvMp0k#-LI#~NVtK^NIpE_b zirui!UDT-8(>aEgN$@kB2HICY+P-mQ!Wq^pvCmQKu$RpHTaP$&?dooa8PK9c&_c14 zvNGe_SJ2ZA!Z(49yys9KGsb3J1>YVmSpct3m#(MBb9jaYr-W8t+bVj(?^?4nCTgP* zs-ud&nH`|4qdHROoSV@DN4HsTIzzOlk)vrQzIlkg21yz)Sp}kDs)M$>B5-o^irY~+ zQ%$X`H(2}modU3we{p6zT1R4FJ3~<_DMg1JL^&6_KINU?SoCBe2v0~#%m$cDHSgOO zuy`eDbOcFkD3n7(N-9U6%$*Pv4zP*!5m~+9hMX>z_rKLQa!^SyeepW8q)RQEcJI;9 zRHEG>@{A4sueY^_f{y&{9Xg#?cUNkkt}SB6PBhGyA%@a^x+IK`2+wSuUC={$St-S1 z;bOdTLu}+Ey~F50nc?rhV@`HhQ1M_1_pd=R-8)XH4}O2^jDK{tzFD08yNC3v2yG6# zBhSlOr;+j*c!lbT<;L=1>aeqEX9L#57YOdANT=~zehmpPmf2s%KK=M1@9s4Z3iDc@ z5c=+#VLb`AT*YL*%LSdeL9SygBPGRah6YOe9nL-iXYS4BoC41+nQwx(!QCfZopv<~ zwn(+4&Cg&OA3=oBv&1NYcYa@(u?jlHeSE3Md6|p##R^%AfM8 zLUh45`jmq8fJ2eRFw3MW1-Ghu=`+&-Ch2>e$7`lM%;C>S&_9hnJ*{g?w&WuF8DEtn z4NLwGU0zeISc8@>YaN$zilnoC#G-BYZ~x+QIH2*m3GQtwW-!XE>Fy*q{DFKjN<+@@mWD)bTD zW~;Sm&(+-f!-!hqw$98rUMtT2py;NPzvmY5;0Y$f@Ea&K=V{?-G+kFuE{ml^EX2Q3 z`jC?i%qzLmMyKn6Lv6_p|Ca8gd+NL?IF`fqh^(jaNYi2WbcjhaaD_D3>O1)2lMzCa zbYwExiuJej5q8cUS2fF~iNk%OuWsJ-PA>-1Z-bUu_d=*hf=_7L2x{|8s!HdFkZ5i< ze%fq(90oyU5ZHf&8UWDLAMU21tt}9?DK~q|M|~AIR{Pm(Kr$0*lNRlkXxwPk8n<8e~r2f;6{CBy12qR&Aq1V63-qwuG zH-4d0WIJ3YP$R1h&fLm+esV|OaQ6f%hsQ9t>Pdf7yLQzaPEUk9_svA7lOAXB`h7=~ zmi(?6bi9zms_*x=h4!E$qNC_kduTPwHk4j5<(?lv-McS6yy9>iBmI8&<_@@+=KVU9ztS4N2J_6Qq zp)c~ncp0+gYLxG(;{f@9UgmnV9;_Ab<%!iv3TyxPKhbI)T8H>Xsv#`DZF5}Y z>U1*0Jn2lndb+Y2^#etbLjh}L`?%~3#}uhDh;S|mUAaVi2ZfOGrJAGD*R_3BG8Jlz zIKi(7tBgZ!!Ans|S+@Czc2anZkK{^)Fi!fKme_WH77OS!)a1ygLH~5C3)q85foK zNw=wn%cHIcN7BcwL|#%~j$0S8F_e$(j$iNX#*kYnS$lSTT#@WJy=gx^7spW%4ui6! z7iZDS++3rC{8pu+*l5!m32vx=r^@i5zcl>YZVnMTCFfx;Uj>gjr_|@=?G^4v$Z%)&uj=_E-5y|f{9Uq0Zkhf5(qj2~r z`x_V-z2unMmwNpy{W(eYJ`NkIAQaR{kU1^Q`mQAo`dq2{X&p_?$%hqnt-fol)vEeV zN}FHb4K-wCTJW%Cc`1})KK1&ilc5EE4biRYJM!g#a{58Q6`X2GP9w6`m4CWDEK>(#FlBRdH$~B^<%s;KYtBn6R3F)f>c+K<54>lFt2=L{P<)!_CL=>66m0YM)*iDxA0|&=iYr zDtRhQ!7Z8XI!StaSDnv%Bf8Dkta!*T0VTHpl-iv6CtGWO~W}fqLS&? z*`R<>?@mwc?V@>ZE2tHB!IC1trDDA({UdG+?ys*<%W6{%-nRW%8Wz%0Wqj%jwQj+0C>MBF zYvS+FCMityV`WZIVrt+0XPvn*Rp+u2q;qC!?g+l^`B6ufLX*=MK3;L~@4lO-9}gz^ ze+_a}Hqwuo^;}22Lv(VMQ+vj87f0o|r+p3^iCT8fb{Mi#Qk6(fJG&*0c;$=uc|i@~ zAbbz(qJ+wVhPA$lpKsBb0cCWQeEGQKt)F0xzZo4)`Pcr`)4CuXn_A=Ak=q@5P!|Rb!SqSjICF2#I`NGt&mno)H?Xu-#Y5_nOf5;#UgaZ4 zdn~AJ^5$_PdxP+kqT!z}&)?&?2rKPcWh+x7v1XF&vHA!#>yWePzfpEdb?%hx zfyFhRSwXsm8<}t-px+t8Czsje7Wm21Uj#o}8q!Cj4^|}0qZ2>n*dqA4b;>Q_5!L4} z`9y5%cw@G9qpz_34c221M3K4jl%qH4j{Eg5YTjkPrlq?~xU=Y+d_CIaIkzD;$PTs} zi7dLC=Tn$NC_~Q2WH3N$U}dkUCs5LRO{P0L8nZqOz8zlue{7v&cP7x5ggbW9v2EM7 zZQHi<#T z=}M$zkya6|Ym4@;rtsZl=H$-B4G$_g4^ENq_zfDisQ=%>V@&Iq0ObLfQIJtll4|*y z02K%RCpwwZ#HT?i0SQP#aD==8Bt`INV?{D0*%^{Igh`U-NQnZFUDAs2sG2GQA`0tN zk@fp+cN5h=H)KFtKke6iAKJ&B{mjfQK0BN@AAer5x!q(|=%RCSbZ1Pd)2cMPOddOr zD#+#H`7kKpYmxP@iMoj%h>mkvtHz$;=;N>t3FvO3M7tb)0Qh2N<}C(i!=8PFbB5Yq zpTyv?>FiFsgP6=EaM{R*$jwU=#vi>$c!=M8f_R9JvbzE&1~pZDh;s+v(@?NDty)~f zKD$=A4!O0seA`#-Ip{bj1(CN<*sVOP8{{_J1Ap0RvXHyBtiSHt82h%dw=>Z98ytr| z6?RhW!``a20Kcz$ybK4`PDIOXtbwnWbP+-^Ct%Ikn5fg= zCSlERn1j~_D^0e|^vs8ug)>wqfsf(LfFGzDGBrnK04AY~)00GINX*%q12kr2%)}Vz zW>Cx_m}8ZusZ7clij!Psm=9RYnVK^+=EqD6>5P-$$GB#A%sH5YkH&fiL>cTE-!cef z;f^L=OuFe;liJb93sF#JdPZK%x*0$+_-616X^sXOVg@L%BQ~abChd$Mn19afR<^Fe z+7Dw`0QQd;QrT4}v9wx81!U z?JyZEBnFe6St#K`eczL%OGDjIT3k2B)}7l1;%z)dzWua>QZZcIt;eV>r?iwVt*gFJ zJv7DIHQu(U7HZRdxXFWo!*lfmNqr{#R!k>#U$ri!&7tei{+bZ4tW9}#Af7&Kv%sEz z4&h3Jnv6xi@n+~{`5HfINCXu3aqlLwg$ldch$vdOSuSxhcst$UQq zrROH&N3R+VbP)8>RP2{5tUhq^M_2IaVLQl*N+xXQ7_uY6OZzwie#v31CNemSoWN{C z5l9p4Df~XXRfI5DTCZuescQdM8dqL%K&25~-1A{Oui}{Z*L?BI8{gnS`vZ)kX+sdb z$-YVFgt{(=9Syiw8swLoFsMjSg`{bbbuDJ3F#&8M?0e&&;oz=>iN(_K`2yiqSviyx z7&f+*MrB;U?^`DDj8iD_JQV0JN0qD`V=bXiHrYTc+1tS4cyPquO$(`iY(tEy0aWE2 zL`o^Y5104dFZ;Wh&8a}!%jb@v43Mw1Rn)>R&{K8Aawon}pH{)}?~0;bl?RC0`@jzz zm04Bh!Y@;a>LuVHQd*hg-^+ugFY2#l3j)z?B5Ce4ZIhw5?&Ar2~iMFY#4Cp#r zL21sB75w!k@#}o?UliP~h4m}{TzKNb^5xWZ--61;xSRd12qqGPex0Rq$e>U{P& zRbf`Os<`IT3B42S=e+C-I&C7j(rkd7T53# zBI~+we5CT#C{n7`#*}ng3x&i?CWirIC>2UNYTbsdUEtR+#MOK3$nZ-GCvfhS00r2;7n)=p$`P5>RU-kWW3wlXgaMWN76)!GRB1p(AG-;` z?z!>0s5-1e`bB#nQIX;WlpRSQrDgra|6LG zA{yF`hGr#10M0XIf$BG-gSmtBuO%#s9JCa|Z}*8|*& zbMO%_wc9tlq+AShYl4V;#bRI&w8-zq-oTAfrpC1c08RHqwHT4GM_h$K1+C5V{31S3 zSqWw=Mb?9iwsAPlNHL)_yU>IcDwKGp6??bH?HYgqu`jk&aBSJ{`Rzac*5UQGXwuBi zrth{XRjxEkvE)Xhbeb2d%NagUCS^@p5;BNvlXtc{02>yL1XL5M44KUc^lmY-eQu6_ z1BNIK@UMB#YL)~unbKsm7jqE4)qV7R%L7M#w|(m-e`^cMBwf@p5<-{IVd$SB)h#ce zvS|;a;&c&7?abke32o=RrZwW>7Ej;%)8fi;x4N4>V>RiIy?oZek?|UOK{P!Gu|_Ma zF0+xg4qx%B-(JlQQCy_rPC_*^Z}VTGlt}S309T(gsdR(r+VPJ}t2?%QdU+mJtovZ4 z@cxcTZj_S(=Cthy;GR^9Ci1g1G1JCfsI{4pXo8dilx(VXgKjH(ZTHas-5y{&B-S z;8d=@)d)@m+SZ!FRyDa<)1v2sOs@1JlfvHFinz>*K_F6D20R(60OF`B#fix2QKo?W&$@LO{cx+f-qutFWqdIfZh z#U;-`#k5EiDa1%C&py(3`(Uh}U+RyC*wDL7tvXM+Y0fvSg)k3cxJgY!4ZpVz?Mao3-P9M2zt@q{W@}{=)nn|>11OB6Fa_dw?Xwo zR8r6PETlUbKCDUn1*J9!zJO5ui)46d51O0sJ6%q>P(f_nfXvXbp6$y{xC?h_K4;_N zN>_u98Cc>2qT|Fh6kfR;(qX4K-(>XL%z7mE(6Q2T5OFAEM%8V_Ne|9gK*%}kkjR+o zc#xv$j@$R!{rI1OUE@e$?kbf=ZrkPJQulXi`2EWZp4h^pi|bNNGKO@}96}~Up|;(6 zj*IE>&-V6St(P{xsLcbgA=b-&q@$Wd{pXQB6xYE99QE9<0-XF!AUP4gKxckSjye51 zMA{gJh7 zovh)}`0!Q?CO4@iM1x?Jtgx^lcmwsxkfUZTbcZky=A8KK9bce-kCjCSpA6|GwC zIPQ3G>#6PT45b!fZSM$L8xdJAZfC3KPF0`Y>Q~K34f`OzzCLj!ph^?$Mxo*qzHHe4 z5tr?6kP8KUox@*(p4$O59DYv=`30bc`|MA6w~#Wr2li+cH;1fBU#B)CZ|xzi@!OGP zGLPLl8Jh9^x{tAqSE5~u>)h4r(84hj9V6?}$uiW)VU$<^9^@3wWAMR4=a^`G;tl@k%FSF=GV5eTAZpU(tY&Fhr%Il^IpE&VO7~6p;FSqJK2ug zX>OfxzHiR*kgr2e7n7awh=5=a5}f<0y;H8Clh%CmT))aB;BwFefipHx>coghK}Km8 z^RJKg(25jp9?w4H@I3z)s{0)F%DvjvNgYF+_RS5ebLLLQhGJlKZ~Pxn9pEA{>IhOr5QX098XI2$>~DNcLEzO^*0^5?BS zI!t5`*+524K$uYowSTnI(MzQY)xu+ZI>Bk9%m9 zH_i<2jrclk{FZAOZbC#BW6+Q74+C6tW%$zp>}%I2yV&2VL%>q?tm>v8r-*5B1efIy z^5W#SAjtZR*S)MNKonMNR~hd?lcLnupL0b825t8mV5m;(=_>eoVG?}r2>kPR|J~am z=Oc8qhhPBgzH|q%3h>C2QxK9-xsOqQZ)Ej}-F$slC}xdF161S7_wgxb?FQuDb@-4e zGg|0I#F^6X(hYFIunA5+xI;kZbB^wAt@D#DTO@kql=zaW2OF^2uV91Fde`f~Rv`Br z^G1IK0IN2r<2i7~>lO{RU2Z={Bm8~2W38Nnn0r29y)C?w$Mv46d{(71MGccwFOY!O z6Jld){78X&IsvrvC&0Eq_B2ta4}LGhgDtjYV+mf(av!oXMR?4S3JuS_YPhX`* zN}a1)Sy6^+GpvR#(7LtIA4sP#WfP~Q5VA1=K+{6T;Ftr!V;7yuH;Ph8yYR`_^vc?t z6giNaLvxT14>};P(`JvCV$)VdR8hV8TrE7`*_tL0?riUH|G*|2+zG~pMixJ5)?Y-I z%AhWuvbm6W*RdJbDBbzCw}#cgP{Y8hgan6b2-~uzn7ZcpGB)`jTjAtUJrenOIMPl5 zzEnR2T@J^hnvX=cOLr?5#7nn3V(m4?Tv}xM{sPJBk?%V?dvhqkg$}Cp0bCWTPP!#o zaOy3SAY}PDU%bMZ|t)Wd<-8gh5xP+at6R3VI!X%Mp2?3fhb>hj6IePm)bbh?lM>fgFx)B z5j60=+gr2!;WU`v)^*ywa%+ta*DP0i$iUmzpT}IMWRznRZe%jOj5m0HJ$uvur?*st z16rRc7~AlW9uE5>q$o)Ig*BiNjPnsIP9((`qwS>fx|wJ|VEICd?Zv;#+sZAZ9UNRt zPTSpsW_<3yhdu%es$6we)^8)PHU}w!vs;d6RUlTn6qc}5RiBf!yPGJi8cK$MO!+sSU*q)2v&E?z*vRvTEMmleH!#pD|F9%g5VU?kk`fyk3`|Z zhIAAUXHrS-O+WHbNftLc3C=YOF*OMfwJ3#c&LuFqoBmC7vYPH7RFQo1N-~?k-nN-h zNA(`q%%IPCmnBpgAA-w_=yE9JMbE#?YLC@XFfOA*)=%Vd@07_7bbrkT+$VmeMbDTk z?$xfL5I+gZhIT@R2mTXQ6@Dou+=n}M_&g4$tq0Yk4`AWt2;~IUgzOfhUhHVnNKr~KTzIxk4=KK)4#7! zPzz%U#FsE;GRE`Jtl*mF6}$6*bCZ-dq$ziLa=5D4EFUo@lKKj_F%G2K)%UFgFF))x z=95T+;)&f}nd)Eg3OYp?vdMxSfu%UUF=ea@VuT~UB44XZNVTED^%GQ=;oj- zN+~U+!agk79ZLZ~ZYo2-AxCU4mub~sy7aJ^<`Io*0}pX_L{08))U)RA1sirrWWAkoz?SZOQ9306%$4W z9YWKn+{#U>{C?q_9Xn+SPW<8ApWAELJ8?cO)#k}-Yopy%u%RWiDu{OTBCelKhilQN zRYhXx?9&0@HrZKahs}!}n`74&!psB)WoB9xRHR~)*t8yz`w$|#)P#@4T}qwL(wMW5 zf*e|}5blqXBUVEwz2U}zWIk6!X;Z3qh56S8zm_JCVH5Nk*W+CP3*^Hcw9GXh^`|u&XnYgL@-A=n)UoVpRJ7bhrRdDGbi~4F!y{A{3jLaGp;ZY z6-vZsHLrK9n#vm13o34EAZj^+6~eNXa$w^Vldl`_;5;dLk!9+POZJ;@Jxj#6OJG3( zj`RoME_CQ!V-=`+_%~D-e!!fA$B=ulyNfQ6*UD0sTGissuXoXuF|*2o{n>(=_}U_- zQZxZX4eN`Y59ccPX0Mx28&^S^BXK7uop6@2EmNNrlj5xxy@BdjT#+mytK#sPgyZ}l z1}*y1?fjNDiHlfyRN+%W*){%7it+p2k;2;LT7O0OrlxaFNXcHgFs zJP!XW2%NvtBxd-s|9l{uh_2wT>A(ocpQ&6iKk-B6E!{%n6f>pCLUL(Et4ZqZkL$Bb zXb#Ajd{jQwKgUbEP~GpS8(VIm?>5c}WGSe7vUjG9ESE)dmsH$4rAci3VH19MB9;w+ zhsp2Fu6YF}34Dt@FHmW2iwE)`Q*2rdEM4g0slROU;!L743`G~rWuaGGFsfILnyayf z?n$LC!=|nf2`$#2^{(H5f2hHM8g| zsUN}ZPSYI+12}wmugA)Wn`k?d+b-lpu7Iv9`pNkXfiptnOsF)a#1h6#kToNKJz;d^ zbtb9W|5lC<;=w6Q9+e1H#>>!`hp}u~>mBru%>S{5ItxQ~B;-2y?Soo+K+O>aa3RdR zD?>*A7`P)k3KZrM31agbNj1G-P3WD{c7!mc;C4T;+Dgzk5i=D;c`BO2K~-0Ub9+Ne z)2#cUg?P0~f-Ag!R{tbv-!;S2PrplN$l5gi`U2G%(PDWjQ=zMS5r2VUa>XnI=RKWI zP8h=`MxRSHc22d{jMS7@A0rh6NL41{m=+QiGfbFF%b?#!X31>@BP+CVa<{Lp9KvC9 z49zt9RYSf&zC6Qi$pmz~n@n;t%VN0hJdviLqB5pz?0+e<%XjfaqA6X6*((sH0Dm&m z0???)o|!69Y^(2)=KFiyw{ zv)UoXez_dxr%Wzpx@=de_mR-|jcbf+^NAv+nA3h%FIA}K+NK<8oddZD{HNFWxJX!9 zNb?qylT$^uA!8OSz~+Gf4_krrPSc5$hzJ%1E;?4>tOWN95;oZ_m-F%RLdMfCo~!%BKv?=oBElzUBuYG@~r@9y*HlUcG}t zxeIfM?1u@Ovw|XuA38(PSF^&~t?mPvx)GeyUHj*`G0Q+WT7NcjYO&Z|$-)a0&t_N{ zjk|M^26@B?HqQ0FU#V83fIv_3yjD*SvN$2(H!6L+m(t9zxS$D1RhU%K&Eef|(>ejm zJ$pQ_btRh7ZQDiw*Jf+*1fE1!KVzq8$E>g>)E_COZ}DTH|`VegJi2rC`z9Me9Jq)D5*11uZ?j&Wp{=RL+A@n2U%Ufx{mLl&>!C-KJ-p zbWJG6@~cag3Po z=lrgFb1M}qR=cn*x5K^trogk&D_@Pd2KDsJ0*|1_DZ^~Zga-EOw==AJt z{HbmKcC##Cn8R3#kK-tib3mj2iWK>E$GY+lDOeMltGCprg%Dl@bY?t%Z1Su7vb=Fk zYgzGm87mly*Sud8w#;RA7{yNmM`3OZ`G&ptZV$% z`*0^yCu=5oy*sbR7skTQTU1YObuDk@KREx4p{fu7qSz;OodHXg751C?>rkZYE(EP= zovv29ZL1qu>Q69hoS&1DLh@at7lZi>r~&<4X1eu%w|c5WQnnD)VTZ_$ie`CNyu0~4 ze6+9dXZ@Y`GDY9nQqgd#s43m`Nw}9?Ya{r7sce-ITsWXN4$fvZS&XjRA1%|%x}Cln z<3mn>w3OC;nkyo=@me(XTl2ALRis1)Z7-VglnAZK<0@M%Rfr*Md>=(R_!NrnLm;o6 zBov)c_19miB(Q6pRKr7!+#($Dy4prC^h!hEq~7#gN1j>Bk9v(GPM! z+I|A>OskW!J6u-x&Lpn>r-wKBB220#wwQmchaIOp^xg%-T4ZR%$nl8(LjMf-O&6!M>=1A%}#d4{oF(C zO=rUlqFhNWST9{7i=0KyG0&mnK%NE%b-o}sS%du|+(GN4L>J(LGDXHYaqe8k~+S3Wl4fO+QAEUFT<(cLAS%bt2 zDyrQFwws!|B(;L3Htt3)wAoH##I;9C*vvfN!;i-UJ98wj0oWwm6ApSUfh}1lP{RWG zbym~QQ$+$2C?75Nt?SlN^o2tZvEL!p4IDLfVUJ>N7=!~nU4QYVa`9_FIcEw$0U@nG zTKte}fJQ^?BPQg$*wI)GqAkFL|F0U$8oYw(?Qi5UM+$m`Yd7=R;R} zx~*eyy4q`x-ao?RS^PXM#y7=)`p^y~?!5|kMvK4mG8Y!)@Ty`Vq{YQpF5|3)n`rGd zvJ^yauj6PY@;N`Z%2H3lbuGvAxeaFV;>Vq#l0rq}3%nG)w$2uitq#h3`p;We&L0<9 z!4uTeLwEu5d;ORTxYbh-FL#8wXVZZ(9|djIdpxjn^nSil9)EYg!R=iEw9xDS0&80x zb(3!9mnM{h0$=ImpZdXcetCRvc;A?}NGs`BMj0h2dUZ(jwm{AS6!K8ITZcSO?kDDj z_`!KV&WR7=EGhimU49Cn`a$8va1nZgD9xM(b_e`iFmJEk9%mj&)rZg{2z5-0YN&N9yW-0PT1%Tu1`I z3?2BtM*(`i&&1H*GvqzoUaOU;4b7T`R<>x?SB&c6$Ts5is4M{BmYYT^qXIwGQ#8}r zlB#wF;YdQATxiNr6%Z1~NVX;}7^z^8`0SH_F%3+gfkpR;7K6$0-KW3(D}IdtPj3Y|*Rem- zo^BQ{S4w8K#!~>)pf4oTM2HG=4kmf#A6V-6<-K+^6Jd1B+Bu~&FZHwhw3&cC-oC@s zAUqVFT_lf)*XfaDM350qZ%?I!Rhx<{5w%(y^j1bC`f2oAO{_hA+E}zXPl4_NuMXD= z(9ZQQ4f0>cS5HqZj`lsv?;2;@=Bfpf^nY=3gAMIujx7Rq%HR_zcBR?o2KN1nSB~}1 zYF@j+&2KfhMBil>a16s(ym*0VA6@HxAJ^XoA16jC_w#LATO-QF%xvoAydnjsTWp&~ z#{ERd#dB7tzVU^^oGmZ4W+w++S)X-+o~dhJ77-Ht7c82vs9K8W#_h$k36la|e`Op= zA1Cn*66OOy$}(MS&HjyjMaO@kV!HQ=;QA5=u_3qvz}RLIacgrg^8@sz`&efQkk*CG ziAg)WPOrN+e3tf)J6D}fQE_attJ{a!h`^f|{Z+)1fMeg;mmQwW((ZT4xaZ5l8Erle zEo3mEN;)O1DXVD1rLlHUiBOT)+RK`QSU2Ubyl%ikpX>Yifz@5jPhH*fvh89?FIiR6 zKFn}l>9SXE&&yJhy7!PM3?dv}DqL?2>DJ$|Zv>Ft7yGNdeL45n*NLtZDy;dy3NU+L zCk~N7Dt!*%o#Gf+nt|#r6ced8QK0$7m&eIQ|b|eWkxUc*>lZ9Ed z04me9s;DZY#K-)xTDW~C<4Q^{%kk=C2lRxWI^vQPKx&Fg+U_$C=iQ{a?G}9xfy)io z)O=wUYpHnLL@FLH=J5|u;#bkj|3|(2$CdLR%#(wIjUf%;4wMmGNlr~oMmA0C4m2O# z#oeCX#lp$dl-|tV)rsEN-p1aJ-q0lt^d6KP$Tf}X9#rKY|M}m>y#K|2HmO-^sGMMS zr3JLH0~sMXD<`db=iA!MQban&#MFx<{}TIM`1f*v3>E~IfdF!#*M^>W;#d9DFqeOz zKMa-HV&2^E1`J`V=%&oo^vuN)%Wi4D^~YGFdD5?i(l5pb9_E>ru9NJS&M=bf97sSS z$<}}nyFEO7#tA-B^XSN37{m|k*o@mgfJ&+_WoMjBTKC;-h5%0-H7*~HIsTBpqfA_)l1DQUj~d;t$TQe{uvFsk4Ti^O zVV-W0&;B$+BMAr?p?E%h5Ti#}#XB3=@>KCwROh;olJ zYu;$#V40`Kp!h{7cZmMC2uWQ4B!M2O9vK^wb%c3@gAs0BgoeDxZ^1#BK{F#LM4?y2 z{9yh)$yQ|MaPx5Sh>`G&L1a*22cb1kQI>=TNifeT%d7?2gdU6B2bmMeG&Vq88i(*F zSBki=NKN4czLWRq=0J~=t1Fy)O2@T(*H!Ad+Y;}<*QNX6I>#FE4ku@BOdliK0;s+b zIW^z!JH1oz1t!;!BqshMtG|y|8NdNzuEJRNnNFFgS5RCr_l)N|A_rgb*|PfF0kW3lQycjWdP}L zgS1Z3;>K{j1bmC4BI)lzsWSKh%2QzO>_GS&g#qdzhRJ+|^9%RsY<|E_D{1o3(2wDf z+9O=M6g|Fv1isd-^CySj zK7!sT*wne0T~m{39_^BKRFjUJfQT39Y(BO4+=Io@QxG}096DJe^io1g3{!E;OC5*Y z^`GB&a}+6p(JSid!*+lfZ?5T&10E7Fgq=5F-syc6oFNh+l?E3Pwn~1OFoR#)r@kf9X^sBmz4l3YL3av=pYJjtOUhkTG)AW_bQ7l1J;t z??M5?kMv!)$R5WhdZU*6qfpMoEvZ6(TZC8#Cx!BI zUod-s*y0v#FS2(JPwS@O%DD3Xi_C4gRwxAT~_xNPQ`d85=A@*(8>V) zEQ!wj_J;aBrd=Qm?@zl}%sVb(R~{v`NcFYGL-{Thtp^a1FKnX#75&$x!LB#9NB;B9 zOs1vY5O;u}_yNl*zFIT1vRm~UbP)z(06!?)>gShkZ*>{kY6{Ob*6+Mh%Dvyut}fE= zC_0&wuZ@odmsew=nyGt4P*_|=I)x@JY~E5yZC19ZtvG$2AQ7GWodAEvlpSh!8vK%{ zI_ryfR0^oL$xS7TZ7K*~=xHDdO4q7na38x3G&Y7>iK*O$Sw6w>)AP+ zVyFlf9~3HEElN@3N1aDz#gtHGmHnlDYYNT@5w-EMb_yaG6}uIcxx>U(q+PbX>PxI-$>ukv{#v%5)4(|&kVF_j))+VGJ z{P~wIf@%qXMMxa^2ZCM)_)bvNvJvk~(g)DvdacN7`h}mFPr%n#`=`0^2<`rzBhwZ+ zU-c6Q+;hE-9C{k@;)Hxk`)~0>^#LAq6y1b4{UtXb!k5<^`G`J77BYB7OJgq?Q<+hS z_VIV7r?^5L+2Hr;5`7epH#`nD>9aV=oy zuAV@4iC~0V`2}daNuKVU#1K{&3ppRu52~S<@Eo*Lvd8Iw19yEBtnhk;` z4!VpVXUvYLtgUFLl)W6ZBCCY^91pOygc{n#YEwMt)w{Zg4mX)`yHuw^40BrBw%H!(wm8TZd^$7P8-6D>m%pC95&!g2^mmyz1Tb% zG}MFExCrxc^}Kux^xG>+X!FG{#slIXSg8f3PxPGh_oUon-r0$i*;PC{t^uHHvoCh2 zyb6>%Rp{Dos*nzyB}p<~Ii z3U-0oyh6rmguhPaCvaIbG0UsAA_LCIUp_!L5N^P^o=`)TG-!-~!!qprR5B(yc#kX8 zJT30}0vF6Cy0KsW6yA5ZWy1WRk7>p+V!xE4cxUKG`vkxc{D``LF97m#Tm5DF|N7qP zOT2E1sbY1=sVp~=;iY~)Y@*t(|3S^_$0WiKL=1gDZvG~IM$GHzp&QOxrZjFyYVB-% zZLInYH0BGI(@_<;)52kwQyGcq;oNkK7i*7X6OJPua}bWQ>YcmOxB7_c#3tHlOH{-L za+*t@O&`4`Za?+&&;}@kc;9GUpCZ2x?(;3&lNQNyx{Na0f8+SgABMhng1R|>lRWj$~bd%k51!-YZi|HEwVR?JS8|Wt85VivHX!t zuaQ>5H#-G}YbpTrPSnQ2Ma2wnu@jR^fRtdItHb9&V{VPGk`93JQkZ=qjV7+Nn8Lj; z5e?Q`U^sDxKrV{RmdW5O?I`OmDbL($CJ5>&6%q^;eqJ+&|Yb6mPjOHkxpKKQrXepOjrpRAkQh|rUjrv7weT-whL+(PeglUm?ltl~@N5oC{EMI7Td?Rk z4sd-lH=%gRfYC%}2Eyp2xIL$bwbZDdYfhS?dB!$RNnrp+WuSltM1`~v>MEs1f)9Nc zB*Jg4kBtop2`LBcVm;)$J`2<&;$^hIY?SUPDWQVx0_NeZ4No!b-0Q);myX9IK9r{} zdtpLUB_O%l^+%AGb#5$AZj_Ul#ay%2nhzVLv9Tb&Unc%9^AbC?>Y&8KZFFlqlCo)= zZ)51EYixi+zY8PmHBT7ZHyHsO!xDj-Ibq7GN?>Gf6(8T-BhOdzfU$%PwZ?AJBd;Yl zi*b^+_QuNqsk|5FqCegINW&tWlxT z=&r1c1f9}KPlEJ3*-yv@r3I@R5_bm-Up9;dV7mo$y{!9zW5s(jEz@QU_ass6>ePhl z&XOO^#TZ*vdWjI%QIEh)-_XiyQs(N6ZSUqx9^M0@iXpT1e-s!WO6j2R8Ur$tD1|;St6yhfvwsd@ggi(h6fQvqW3E~W{C(O!-*RF zL6QvIbFa<*n24!>=Bt9&4Kl_u-dP$&e;;OG$QDHK#mr?BrG0*C=S6tZ-~2p%pBHzX zb}x3lWOu!6eH0jQxf`KChcp2mU=iX_?Fw~{IcqR3NB~R%=cV!Q?umNpbcDy>IWbj| zYENIRr8c!q=)+IFj=Y$~LW~nz3#Q5zHXaHB21Nr7X^8N~pT*f^;+TG)s9m>;17(Qw!}XcIk%d$p_l{ro)ZJ2l2yX|e!p;XS{FEkbX3IFRaz#CvCF^3H=+>q8=ZY4 z#&(lpJ4eXd=WLFT8?i~*!?E7Zudj&9IW&{Q!jUT&!wHz9l}2a`%o&oC*pmdqNt&ar zOg9Y1>3#pOezb!@SVO>OdflYLKdL_qbC||-+j!d~lzAeZbJD{M^q^11K#XYu)BTv% z42(I>(Tt3#Fe7EsXE?+&>ug|^2^*8Ugxh#VgV{GjFB-1!KTtnLz?oEOuAKFx!=%n} zbibzInaRRg_Pq3)=!s)ajM`S!VadW%1M!$KU@TH z-p!Y{wTgIA>cM5I>$b;Lmq#Y?scPfIc2^cpY+gz>T7gN7V!0-X|$N}YQ6l?^+U zfH*cAa6XX{(4J zj8UYw+xSm>#G!2|;ozUgPHxzpA;6eEe;=MzqUa`A0kBE8T`00>Q)XgNj45s7ZjAOg z$V8w4rN{k20E5U=pd@8#OhHlOZUHmfJ?vTX2`p1{ImcN7#pDK180$Q9Z0mPll&+f`k+blL51Ye4VyN^IX5 zZy2j;jFB8`cF6ng{qJwp(*xtn8k?9zKjeCt`n*jY6Dl?|AbqlWYq*N1EDDyiUM|dM z)LQgsl5=-pFg{Iz=d}b@kIi#x%xB^aL;h#dOIcfJ>iUf4gobqdIcSzX1P6)G7+`ki z<(}0qpxvC(WRG^&!1#D`27uTC*vL1aR(o8s%(lgOKPFVDb_Zq+73&Nf;z;a(@4>D? z^4Otx^!);Dq3X5Q>9#nkvWSF^3FV@~MGQpb&X%buSvh7Ks^Bq-raCsUT68UQjZ2Lp z;Bu9u%TK)iy({D)c81Qa5SAHHoGI}2H-6ELML(ED2yZ;~mSOb99{{K$_!RtnnoBM} zN=fhF)&#xP%Qo6;2I6wcwlHNX7g<{HHp0-*N^_kTqd zaWpjlv7!+s>{GIMY*yXsRru`qMJi@2DCj#d7VWfK)5)K^8V^)GabmO3Z%HpJ#D|d| z+#|IngzCn(g5p6^2L$lIc{^bLE9hMcVRGvd2UnMXwe&&@Aehi!F#9wQD6u}9%NnO| z$M1FL!ifLuQo1h&rI-omTB2N0$6Kjv@IaXlCi=fjIYcFo4h*>DL zlbjRrri1?@EDp<%_XRZ-FkLb*JX{areSYy!{;R`3VigO-lmSrP_Mj?cOs&16_l9}; z*QRRZ26R&(Q~?f(yiPQQ{pqZ3+@b-u&R!fs2|8gMb~$k))Bty`EHz@xv4eC!T0t6x84D220Jj>HA; zfex>}FR?!RgaMEeD-ck#T+eQzIbXkqQh5$_!tc9EM_Xw})wH_>|1H`nUYl0Bk)?e+ z5vNvp2UpDWsxqh$H5G#&M&OL#y;_cEgszxgYPA8W-clV0InNS$H@&y%@ z!#7baBM;$Q;$M*!GG8@=d%%FxNoixH!gU-z>egLFdu6 zYw@Fq4KpWX(xt@4!av6@MaavM8BbKg^fLv%lmt5TBZjvRlz=WOlQ^)1ynf33=6XmHL)w*YRWooR2sN&n6Lo5ov zf6BU5ddI9_V!!u{VZ_*0dqLDy_GMK1byv8X%K^E_3^3?0_WdcxX01*ybd%5bfot|w z;jRS^Ec?OTiAd(R8QLp@w;|ueSxOyxx&gZt8SSu!EIDtl^k{c-rL;6G$pqKq>g{YG-x7uRw@pculcwM(ZD5JV> zCTW}h+)xwxE~e4pH4DS5O>$`Kemu2N+pjy9B9YpM0`71f5zv92Va}zCd)r>f~ zMt#fE+oN3aeG6|jK@f^JH-{^(HI?ja^jF>A zF~YHayLD0OlE`VH?zCe~bt_m_F<1Xw?U%9oQcmds2QQ)`pH+#s@ z;;tArQVTXq*?RonnA%^7d~&vnCuI7pMfM%djq4o>dKGrBNuZ2*uwNo&6&A!57ZNzF zwpB?zIU{ zAKa%q^C|P13VBO)2fIGREC5>H5%e0k91Qmop2Bs0k}NA%LUnz9dt5?dm_YW?bncHX zRe20;iP$Ov`6Jr;i)Z$^WUPxQ2a>|Y0WQYrl`i_~qD2|+eSd|b{_Tz|n}f@faOb;& zRYTQzJBtbyc|75gbwk=>zvxGaZyFxpn5yF zPLK_u!>TdWh*s=uRi}_*e4Kw2Zb&zaQ1PafT~kVzUU%hpYz}a`!{0~#$nP#IHo01Z z6n|7XL$?p%y4a7YJQ8V>L-)uT6k3`ft=Tk=zX3yl02;2)0FI0GrBf<5GYjax+_W_d zitSIBVL=2ZTR8o0qq@R9X$g_V#rdKyyDRgVULKj8gVk*os$6r28soX6uQqlh) zycy_&avomEyB050Xh12XR;;$zX7Tjjtv%NIw!rODd9y0CC*E$t~r^0`|@K_#bw+IIZqc zD#8O>Pv@R}n^?Z-4LLK3pa1Ouov5gug71>B_JQ`EQvvG?9(Q&^UVhq(&dmUcFEL@z zt(;{P(i^&tq4>OoVhoqe0Fta)kKS|N1UNRD75gHX2S(ffV(XoPJBils?}?3xJ+bXf zY}=mj8{6uMCbn(cnj{n3wry*Y{O6o{e^uw=z3Zyo)mOcDb+6BQ*2*)PbT*^2WM%)O z;JI#EKW|5TINAsJJaj=DE`PC>6Tax1uB);(*V8ekSk@HLQ81rz9&hkgxc#`t{ZvUV z^af$vhpHHxo)PRQniW~8neds%uehigzU3EZ4Qdf4l94hl$3$b5Z|D~rGZ8T5*v_ad zW%NR8y(hfl=%&MT&^7nDP56)v$U-TaJ#CJojD!yKdmRB8O!m@`sbv zkvB2yg5(C^MXvBuHytRZxPo{SX}@0IxOGh0y<7OE=`2H|kxs6ZZao%Zme=3{Spjla(6aMCWpXfx@Y^tRv_hq`l-%D#wdUREWyM&2j zI7O7@1XqID+}x5VADlN%K*LYRE#@ZwJtq;d~}wcpch_z+eeI!~G^ zYE9R@@)XhaY*DDa!^+4qHHWg_-BpCSHDC)k>DO;`%%Z!J1HiUEvdEIUGm}GOl}*{z zGi2q>l&HtVN=cNi#N#+>AheSl5X;eq@0%&y`qgjiUxg)VO?U&STF9P}mzaOvQ%!wr zw6yMNiVr4lxe^zkW>KK4j!v}E6n_YCayrlb&70>3psSAGzV{>o2Q!?^VRpI7kln0T zcvGaI`4u-74<8=?B{y6?1m$Ye`8a+G#;J@_p7_LSfr**tZR3~rZsQbb^^C8D-!t!{ zcu3xo^iwGX^MvGGqz^HD$aLRGu&&kicZ|E`vqq0Y?^FRB>T#UcA&Ps|8&x$RX*yEA z$e3{zIex0o5c%E%s?EcXdr^3p+-}j|ObW1&{ z$gW0ds3>T#M`yE!cHF79ynbgteXJ1uL>l@nj`7rpJtUz-t=Q6Yv=H$;NwZu?xGTyw z`4WMr?MJ}(Y>$RGpJ%GAX`p}=Sl%Uzuu%bU!~OZzWuD!3c!KHTHNFPZuM4@DxZ%Hubo z(ely@Cl;LY^q|H!LHqN-(Xd6`NZ49rUa~jXI{B2$A^LNsEUi{-@4M%Gy77~)^?bQE z`cjoPUjfre^f-L`#f{YQvlv(D3dv3@ExQ~9Zupu9vnB#V4 zql2|lW=_izeQ5BPxxrb!yB=_hLu<09mlyG%myRqgxjWx)1aB1Ps+sy=<78o`+t=<= zhWQ^uF6YWr<_5fllrn}!?CTzXVFf;4e1av7(<$xwqxgh>doRZVVHX_rQd@3%o&&=v zUEbH|J9%IU((uwOv4vmzqD&Erw~^5Y`85*MNa4Y13w_=m3KOo;GyN5}`zjMWpQ;be zi;>GnicRHbzTU@zJg8l&p|Svr z-B@YoJiBhoi>6ZChqX=9JkUp#k&Z(Ac3}3k>nINYo(5N_op%zy<9c~LLku^>|Y0R%SprE4Ly+6u+?q@fA(tL#ADrTWVFBnkV~dR_yK7sNZv9U*DE9% zyyN`;F7)k?2&M!9Qvc# z^YZlq+L)JGe6L~&Uj-=)+Lu(kuAG5{6DE8?QcLYmD5ee$E47X1s-NP7|M{p4t@=dI zg0&C0sAi-u(E4+C>f&|Jeky1^&r)t9jy$aFJY}E=-lH_pE0&tX^eQt#V43&4d$&8V z<0qZswpO_2LAAaFS>at<*x^2Rj;mvx)vnl}7@GSk)9l%o6Y{S2uRC2?`rtkq(L7xG zDbNz~-e*cAGSx+#%Rf6y0}Dat=$2o%i8d+SAF^cQ{Bb$iIJ16%iztLS+78O@P~8d7T$_z7shqXd3@iRG6nI z4Cu0mfVP#o(%FSKrH@Ub8`dh9AFa|YOD?*F<7uzV9}E;9uyW~T!8}Hudf7q>sLbe$ z;B{f!1~4!FKGZa_{j^%|Ei1ZY^( zJ+jA)433?KD%CwSJ}|lA?l*r;e_^rmVv)TWhsS z*4MnnZus(SabtNR-RJ{Gm1Ak>|Bw#O|C9#)m&E)B>2Us|J1MWYQ2&sQmXe63R0<0o z)MpAS{(o`Je*@zG7uRUI>!~d@3+(;LgaF6ul%zOC#NoxFpNj9t`3i=KsG)`d18F3Z zz!@r&#MxkeEM6x1Rd|pXzMw}ejFNK3f;m}t{~xpB}rKB#wFb-9TuVAdmzJf@0FtR`tAqc`@N zrALXuVRb^y_JdM~aCjAxpp9$wd}WMWPe-kSM-Fqv>2?U{Yix4{@zTShglpJ7#yDKx z#vsALKgAS%2Juuzu2;f`%ct(v64Q?x1wTjNgkTD@2+y46{^_#CmiPtOM@1loyIqGP zB8Er*NKK^4MnEIw^llS_X4GxvI3`?T*o?>z+%Oi=XdNoo@anJ9sYFJ)Gi+zz`!i&I z`wZvyu9JGLAr1UW8;>+zWV>Rn9>+N37|hV_mot-K8^h%qOvCMKWt;m4Wn=~eafklF z8#cDon{lgugeD>FPbFaV5tugo%$yyGz1J&eyvQ<^8az%wnOSF2iDTXVtOk!`A}r`f ztxdeLG*z4waX zL$j!DpAD}~*akE&!8UuY<+d&aQy1FJs3A-+%BvqUn-r&I4h3K zu&6-dQ2G%X@J>LW1w8~&H1HhJu{pCck>l)2n2x<~N=cDQ!FYth2quQWvVlB|)$95o z3vuNKMi;a67YY@l6y~2(TM4=zSjXkG@>r06G^YQ+dl_gffl05d;I7(0)scGcGcB8X z&XPyWw2G38{p1pxkp^kspAsgdW#Yu8+0;BDxavY`$07nWFJAhpG>uM!IHDd}kvdH~ zp`Rs7g6%$qI(ADY(s2!(GVMwMe!IAjJC+|EKT)K*gAGXREB1BHsmSi!v}sqS5Qvq8 z8Cz*qbl%06B_+2WHk1ZPoty5?g+<4Gcq~0U!L6xGL5;AYy2lK*(}Yz;BCt9)MKrPP zq80L!i6wyj+9?Yr_bx2=$+0CN@<1L`2}hbvl}3TODTwMK$YS#I&!d;<*=6)u(1fA< zI@Z_dTGM`aRYwAawHQ7B^-E0zs-c#g+gwo(YP-3hK+kx_-znx&5FE?sm{D(@xc!z* z%Gz-09=6~Pbu!vjA6JKaAALUSS{nU)lvJde6@dVr0(Y57UDuPNfsCIO)Uu|KpQ8aB z=fgdIF**&o^|W9RgbQB~^s9;F&L$bUa-Ee_AUlWTO40MO(8@#JS8H)Ex2q`ZK_)~LUie2? z;S=Lkw~eg|a~40U!!=L4w|s^1XW86K(=@asT4aXUJgIfIBx`|acyYG2k5!lkwjzM_ zKowwN8m!;Bl}LWp*wNF4d~1!_%YkL((%#vY^lGI~;m|~>U1?5)sY?DEu1-y^$p(Np z&SUIgku3@4u69pOrK2oj9-+K18>E0nL{&edK3*;2FXLx>(HRa)=i}p&ysGmX;1rqa%)&Cgzc2Sqo{dR?UY#i|2)=ge;h-f6DFp zIQqV8;s75R)DH%kMCPZ9O&rci?Rocyx%a8pzqXRi5gK)4ViLAlu`!M#L2(AOg4x(7zM< zswp?4v$|O{B(P#A%VJgdokcu<&l83iP|1IJ`Le-K0}rZr45=rqajp!C20)ytVdgh3!HW!250 zb7qXFaNtuv?$Wjd&eXmKYC$+>@MrmhkO#2_udfJakj=e^dwOeS ze@Vh3nU8TVPQm_dAMdaO-3TfegslXv215IG#3bC-&*i=vOK ztL^1Wnl#slp7>Q^SH>{jLrh+9^w2bQF*TMU=H(4H=3zV2uNBks0P0%RN{N+TK=QHMfE*ve^V=Zk~I@?kisnJ zXw~d%s@2MyV!L-sLH$rXBLh!H>w{&M=d(}{8S0*g3D~3%ou{$PtDDp|c;wpISrn%2 zkniJ5SDDkDVquXaEt#_cJwH<~38g@N9d60Lit52a2(;E{mKfl+M%EFQaVJJRD}a?2 z_GP47pPOhVUa!)EzGkdy8U&iv$?h+EvRUhJS4_%d%v&+U%~enugE$3`Se&&U)$DAd zuH??uFIw(mAb|`J*6tXnC8O-4!_sirH1x=&>hjwwpleCtl1Lf#JxlIIJjLb|E>_Tv zU58g!Dy5@anE;GFef%h0IzI(mHrk==@VNrk?Ur`|dt!3VRb z*P1mG?19lclmQ7^{8Nicl&w`X0kW%~&`<_S*GRw+3V`BeV~=fC%}&aS&rT!M?xM({ zJaAzBIvlIa&1?r0=abB(#vz2vAxj1dJ|(l2E_o$yMI?gMtX=$NYV{*~X6?f^1ECBjZ9K$kL?%YvB{ojrIS!mpYzK$@6)DwmnRVioj@B@wJ zKQna(05*Kml-`kSR;Tje9mmbrC)gYLtWn(;Y_)<*55admo zb4=BVYpgx-=g^nClOsfhtV@XItV}?95 zVBPz&5O2+{(0rkSh{d*MfsPwR_ina&)3rAQa=tPkd($2|tHWmc#^b8Jd2;nHXfOuW z8)kAzC4(|8fwWk1=UI_E{Sbm?@LuYr+5HIyI;bol;IU#A8TYAWB#cg5j&Sf~OS(Hk z=hD|(xMdHP_HoX6bbBYSGs&ihiE+QOBQYu4Syh57DuN{K!Oi$zP`(DJ_SN71!@gO7c~AATG%{ZJe>{U9Y!mhtAd^ z2uPWEy#+y{gmb|bcFr>Gnck2C3-$UMLGisA+<2|loh@MrDsJkZKihYwwrd>J<2=kgK0YlS`6^z!8na5Z|g#OJ#D>mWK*`!j~fyeOum)k*23qa%|oP>!WAtt`qlHJsEW4Z+Vnv+VLpVqjue(^m~^?)TK{Ve~R( zNWnu1bE42K5tO7N3gMpy7#~x4iHTHP!g#cKXuMlNcxaaoS#-ZaaG$pthG{LYr!C`4 z_Ve;O(9F4Dpl}I=a4_R!^Wr0pW=|Si|hM=dL$noo! zy|>Tc@sDq}rKd%@g6H-`SpGq!vxcG78H zO4n=b#|M=!Xq+i^M8uYR&C%2QBTE(Qd~yBE z2B}2t1fFKaj9YnMU^Y9Wk-!Zmn;6T4t2N{@_Nw*7pcwhX| z7m7O?>vlgEGvj^dL>=B9@T(;?k0AY5*=E~*G5?2q{EXm;hQ z;q_qVu`9WHr3nn!0OnMSY?nY=GDO^! zF;uSC7hRS;gjUOx**o=U;f)~>Al8}P1A5S~%N1uaH4e)_{w?;cW#!$LD zP6?Hh*&4(NJ+ov&oV4j{gqb5Qu?4aetBOELX#|9P68PvjXrS|38IV|DBHyfZ6<>W> zlZS`NG3%0IeC^IZ#dDq^vFjdQR#BnaZf`Y>;H|0dC70~V*A!^{{HuMqPBKRylT72S zJ?hJKz#EwwC_6lcq28NijQz1>T%c~WpTH*br5EcP)k*^Os@ZW_=h$6UVk63DglHYoMq)Fe(#s*C zbWjn{9sfPIC3~C{tDlueyCRsLu?^!k{Qk!>-O$XiUs(1}qII_BJ*IDZy!t-)@MhPS_C$-AKT zdfIENPD6ks=42ToOG885E5E>6U-y$kyP&Xpebv~lDQdx=6dylves%fO<{ak`_)^OP zRq}s2%>T+T|4~@}Bg6b_&13z~`hTwfTdZeqoWjfiMG7siq#~>)*`mb&W&WRvCeD-| zMkpMx!jx4;C>nt2WHZsO(FIHBP15%iZEIc4l&1LwEdLvzy-H7p(;a~oS*6fu%zV5>TlRK{L zo!@YmD-BM?c?GJ<^P(0beFQ`)Z>PVwz~cv2%HSMtEI)ud@WVGI?KY?2&(p%x`JhtR zxX;1R#^=<+Q1)Bd{LjVx(xBAFbMcP~boBQYkFDjSZVGclIV%ad`{fpBa;mVoIb)S~ zE=tLv!f-)xF07duiF_^lXxGxkwLwnp>{15_-M1_k?0808Jy>HAZ=`A+%u^mwIR77=?)Ks4L0yuz> zM7eeF*Qh%gJ!|qcBFX3W8Nx3Oo?$|ZBI8hJu}o>NS^WAwh&0honM*IOw4)Xj*N$hH^V8(HYs={>otrz~^x7+DjIBjwCtbr!*QI#B zAF;b;#(|J9P_r6&4Qd{L7CBY;p@h-Quv!amq8PHc@)xSr3eC)ofV;f%SJCn|mjUtMF`!|3 zKs=CYbn03O89tYR(K=~B-32kyENXzGQ?nX;!32I{8Rr+3Y=M?`03!-(Y3;98vL~Hs zA6b7iHP-2?C03a_j}P-)Rz!+{CMefOyk@6bgs2eJ`3c+V4Z1DZ(Rh~f0yy~{RG2i& z_`*tRZRX>$IwX93tm3~a1Ik=Vt^l!$l#8|w+#4&=d<7ETG#tj`ds47jGd%v@8JuRT z(omBDHa25k=o;UY&Q#5@zEvo>wRC3u=_{V*(9HGY(oJ9Lp!0RYokGnUq1XPNV2W0v zLeb)nVRhCDY{rGdFHQVSPxC+CHC-i_n-SitI=6!ie5J_`-WU{js==R_mw<_2dxL#n zwuQaCiwUPI z$abr#id-rqqy&kTv2c>cJq}O+gE3K=s+6Tk)^MnuTSw%j{8CC|ZbB*5gwz?>O|--7 zh;AWYZC)toEg%0-wTvA9-V=e@nBz<8R{Xnx*zHZU$|l0QYUA*Qnmr7t_+h(yyCvZN zLZ3Y%*~^FbvItzm`AF#_3&gY`3Vf;#WpK>$^jtB)$<$|Q7ks)2(Et$whXp*tFfTqY zH`cyj$XIWC*6e<%Ik4s#3wl2q>r<4*An#c}vmdx<6uYmvi6onc-`$!$5Mv74f>S(* z=$z(qU<~yhb2FT$Z2#i$M_Sb1t0Fe<%6$L6=-bwfe3Ks2Z~=;DCxkq;5Y=+lF|rbU~2Lq)K?WrZfc5 zFub`fAQ9;O6Ll{NBCgw4If8u})fBu)+v(Ty`5qpQe(Kzu!?7RPFz7fD zMwx_sT!(a__`kMaq?ys+ksNC=g>g>|*87-OE_sCDGXOXPaiE8e-yP3iRosghSA`C~ zhHGlGH+$uyAnm&_6qJy?Dy1UKX8mBOT|K>(UE#bhWGLZu`T}Vxm@vb~{%J2P8R!-= zL=md>Qa0T?pVMPx6jh47=`)flBq07meG99hrF^yNrU-tr9ditwEJ zxM`t51A8MX`>mqwOX;MQW3Pz^#rcENpU?J+*|T3c6$icgisQDM4h2-H5>xy)l6**# z|MF-ep7uZjcajY=L>LjXap}08R;Cc09%u6GZ8ZSSi=jx@`8Fu03xFw&VT9R{%!%p? zAdFafNNr(%KA4f#J+1EjS{;6tP0ywCtc=Ms#o+RYg~H)^ILq~72K5Bzg4z8H;p{m= z;oad}8#-i>YOrn|KSOUcb-NTP zmk8L8N2!5e6XEJ(xrc-48}bWBRP-Q{66rdG;?vV{zpZA?e3)T}+ctO_DKC+0sO3d0 z$%HQJli)k$Gm3z9hJHZOPk%|8^$1pg#gjQ4E~j(H{zjm6wf<(cUhM)`fD>80{KizS zkx(^bcUz7{BeN5d)5h1u*lCToj)pRE{RY7MewPAO#$Ks_$f;oSAH{n7VueXVvyvWr zX{igsZ)sKP(Tir3FIHN*+FvIZ;GrG)&+cUZK)wW&6UbKc$3nt&~n!_BJl>poXhj*RB5$b;6$}qGIS-f6hW^*ZfF|v_JULIy3oqIp9Sn@ z2t{J3Y6`?f-x)6@siqqf_@-Q9P#ETE2V!MuDtS1}T!S}!<6xF{!s4ca{yqjY3Qyec zKOXkF$x!-kah+d*Z$58M?AK~TstR-n9OqLRJwn!!dgEQvr zNnDzo?l~RzIoB*T14C34URiUJyVow*adX1hc*IVxe7nu-Svx5bqnsjZ>F1RAFYKaF zN=KiN2n(y?Yb_1Z`TCaD{$BAh0fk~ctG_P)yv;YIFz%KiGQI&p58uSP`T%SBl|Zq5 zlns7@y7o45ylx!CJ-zh=X z@v)&2@zq^zlX@oACKC(EM5O`fHz97x-c+7_;li_c{`gR8PWYRLd8Dj8EiYyYBFUb_ zMuyuh1)eVhkP*qs^u>qfvB0kQ9*Bzm=!nk&Z0QB8buM>7Mu>LVmDp;VY3MRV2lAm|W9da~5QJum>ytA`# zWQ?YU>IC(D)oCduRpCxdRs0TSu&E^<&@V!m)61xIBl%To zMW>fu%|(9y4+v&@?j>?d6HgIOKf^M`Jd`a#l`d%@2?;am>77-%c>qa|-4!+%>E;*J zyV3?bG=y@?bk)pNm+?6H=_Bf4{I?v`rD#>-#d7B|*+$7CHkijXSF;s`GB(29(t(O> zo!8qjTSE=q(+LG=IY0s(tcwk0-l_Acl!RNNhV>XWtCT^fV#0#9mTj`P{V*W^@#5$S z1$BuN>1MjXLZ_gdt|(33b!-9wubw^(If^EayaczsG~?UH$0G>ITC)U4ZPjIvIP2QC ziGb_QudOXbT4l!*p0B|oVL>V%=HdN#reXxzH(M??iCzXC0yy28_!h_@FV7+O@@VHe zFvY4^Fnw)R=w5J@LnGi%`H_7z@*tO|dtj%mW2KWmUR+Z#SyNrv%z?vD zSp*-c1S#tOfKRY6psxOK=|2ba_6m2jj3FT!B!iAJs?6cck?1~e))I6H8xtz?qq#Cc zYS;NUXO)yscmB6bn(vNpi15T5zBrvy74b;8#6=ikQ@{mm5K4ITlJ9oc$TBUxV9T$L zYa1yr7V>5E(?<@fr_<4&&%^n}CKPp9yK~o^1gBPBHI~Q3I*@_$iX5o8x5gP-3W5#TmSTG+y{RE9O&JiNun0jxCMIL}YXT-q1`76|+?2<8^&r=KKV~8*-liw$`B zOk%&94QnjlH*=za*3u{~7CFEVYL8M-XGTo+BAqhUFD8y<6*jutuKyk%?oy}1SKz&M zC<6MB`&NAf)KbMT@u;i#tvgaAu&vyCNrZy+V?dsZEatTkCLQ;%?A5WV> zT%V$v-%wc3rOExCQu2H^VXdbRBt#;A4CFOk72H^mdg1XOOmMKk;r2pGaP7*LTvoNu z?pfH1`7CNc6vvMaPDUq3=ZrF%ki~BPECm#&v9OJ+ztgoH-k z#;QIsc!Ki^ve>0>+}2rMFte993^iVX;e8x;^!4jZfXqc0mU}#_o$a}8h+2A8!a~F7 z_+f~97R$>Th6Jz?O-)8Bte}7G!YuVYMsI($o8a{=*?@tG$pphDn8xZ?wznWvSMhe! zm-Q5t1Z+&EM=5l(VSl9T(VRSM!vf@k&`kGMY`3D$({t~;H8(->MmvzWCK|@<)SZH- zbwu5p+;~Zso%}-kMR8gTjYr;_BV&pe>P?quhdFG6>MlYNl6} zfAfzCZYh+HYO6Up=uz@}uH8Lb1E_>)i!~(ohWh0md*RNy8yr9{HM=|O8$kHR?FP7d zxQ!%%hkd*0!6$0-9VP8!mhxM z#QsR&AR6IvM;m3(NG>5ajR1Dt?!%`19M1+jLec~ahQgJJ@0A{YX7|k9AfAUDZF}Z5 zdGOtOc9h)JX7sQv&DH#Q8z7Xo&=3{WJw7G!LMb&VvJZj@O2GJg_NIW*MJc&`t8~h< zN>L_*bt%7^p^~k-v@0;(&*uS70sJ$uB}TTg{k8ktPw>OG&y6{@k_OD2MDm$gs@NOy z1~$(99JH3M+j(fGUL4OMJc{wb;7eg2<2fhf8UyAQ=e@Rve`>B0@%$wtyN5#mj z|MY!YrB!&x|0^Z~V$HvOh3QiGz`Evl&{`3UD5E=jRsrFt`wY(MJ5`-Uf>MmRo^8st ztKr0-*LM%GSzB?pUF13!D8TM zDX8++2X~l8`P?L9zb*L}f~FGl?ZtO`KV-o=n}OdyDAfq+m`KSTf=Ofltc}$MQ=*Rq zJ^s4oB&D2=)y_~&xlp(wPu!miS>(P#i5DA_AuBNSjuN625~}6)knsbYh@}BTpi#z?+Jv?TN-0FU@Ic^sT%amM?A+B z`RioKP>qAZ6*Y~VFUE^>BseY;HqR*`Cry`A&(80+C;n4BroxR`CsFj_CMnqXt8UL*|}yp|B#ma z23f1lB+LSBDZm&akZ^#N7*^_vw3E%*{J0ZYeH2IRM=iO`e5!FiWwK4agkXU+TGZuf zy7P!E=a#o{f=&IK@7vlI;m7u-`=-;RbM_sdyJ_Ug7YWJ)B*UXdz;3J=Q}rS%xqUpH zkZVY^-IAe;9^DX^I6BUrQoANK_>r7u)$r?L^qb%*qy*j6mXdB=ocEzAE75JcZ&S6UxEiv5|5h%_ZoxL` zT;ZPLqV1f_bl3al0)Uc7DkwBbH8%t#^`(!T-boJ)vv$q$u&|}wjDH{WuQQ`$rc2cZ#>LDb8sgLXZA>*-oN@5Y z(Hqj!#^lU7*=kr-QyC)3_IkNlWN~@T@fwn}$Clad{S#0r5+_X{+BavNcpdJyf*2%>TSZ{M3e!nXTyoH&>2|WU#$-gDt^;>uNQBRIn6-+@fVPV@{$2{ky+w|6!JkiOHkw9@E`%dO8PY z-f!xsw9k)tesKg(ln{>J8LR^&>Eo1i{tal~a*L$f0C_fi&ORby8Q5v((~?e<%7tC; z^XZ&}Gj@$1BDx8!?J|^?=h}Zt)GX>nNg&xRX_Wt2;sV8G*e$@>L|A7@2wJI|>J2^x z*hL`pe&Hd3jQe`f!4cT*glncw2bHlbl>EeOFy|IVvECsp0zX9a8BY_ zT|Xg2U9W5&JbpyE*SM&|iF#wOI~_`_h$rqS0G22)*YuxRZ)>JMI}@IazX?Y`B$^u4 zi%j^XA`sEumIbC)%@_ti+@A_|LA=%u>zxU>52LnA5hDQve~>ZRRCEVss_qj59ih_4 z#O(=&u_=U%8#VBAC=1UKba>FYjgh!7hP4T!2WQ$q9G3re#F?4)4+y~?xj6t?c~!vk zGE(oM4Jq;%oTS$6s5_e@+N6~PqbAO4!;0G3z?6f7oDV6(To9ROJZV>wsZ;=LEx7>u z)lm{^^#XK>q$O#S@}JZAg7uG>3UmiDae~Ja(*zV8t7Ne#xpbQJYS2+0e`Qtl8c7WWY#xaK}Z{cD%TK`SgXtlbw zh4AB+k|vC3@^uAP(<9SUjVnmzEWuXfgZS z;Y?YohBB|pJCu;u^(ibb%@WX#c~t4i?($?%VQ9u2GkWFIYzVvjBfm^)1RR}1{yMy% zFfrT=cc|5~`6EPRnEetvPU_}76sK%@-+97~aA7Cd{}p^D!Icjeiu-zy#iOKNU46r^ zuon`P%TdZ#JBrZ!laA|~#jXbc=Uyi9oz3q143{TzFp)rf?=2#TcjbCiKMENG!-Q&* zM8kBw&(p&5RIBKw)(Rm4nFk*IED=0JJ%1QY`$~V)wn{b=oA4ccdsy-Kbiua#a1P{b zl?&0HAKB4*@o~X z%u4WGLk!3#%xbdvYqX=t1rdKg6o_~=2o4a_tyqzG-^xqUcqOyQBd+bW2-5_w0K`pB zS$NXD4sXJOb@a(M%&!43F)}*JCqGr3nmMdMGlu>7(*84gwKJCoZOm6%eJBSGO0!gR z5`J;w-!tyfc+LL3xtu@&i+)M4L$!N$V~r)8+;6xRwH+&ncG+`aOa1LTw<0UAkS#b5o#=(UiXX*qrN zHx9kwm405yGJWIqy*w=l*mJ;i2-QW`E>;{3A#E3)UMjb^95Dyb6_{lriEk8;#j(1? zi*J!zm9?=qF>eJNxDP{W97y5WE@M-&^htf)D-`NYN0|8LGoHND9Z`9oMTa`ZkRhIK zv_Zzgl*=8J$`utcFJ;v6X4W05x{jh`A7$UhrJwfm5uoolc$AhBom_`ll5~%L?YgqF zHQ!Oje(gW4V^9DF$|SRsQwD{s8ac@r)iHm2sRz*!vIs{oU9^j~94s7QA>& z5o_R-ZHN>-kqy#gD)E&?c@RFFh(^%QF(~InSlaP*-J1kN&%!f*pe>V+Z=IsZg?|&(o;j;}>U0%B`o62K|x=dR8 zc`XDzXmhi9*=cgHsXg0R&#=*0vKvE*$T3>Y*A|#b@IC;?M=NhSZE}#HI2sx3RYfTo zDlNB)@^u}!OfG#rU7W2(u9-Az7Q2+@HtI!tz`Qjv%&wlL=a^NUSJ9eEVjeEkD{M$< zHgezUy1|M1XWaAV`;ZQ+0i4fRSm*5GpvpHb->H;2|Gmzbi!u-!)HC!EOkpSeVCU3j1r8hl-!psSYyhgl`^y|USk(ubD>sI6K= z#wtH4t%yU-!?1ha5C-RmWt*YDcS(%ZXBV~oHMr{pk*JGBxhhWOQKq0lSoHJignNx& zXEjTqltYz1gmdZP3Y6t{S34hkHIeM<##$h?PnhSgUaQAFwcc-Ed;+)gFClH^bNxx( ze=XOs?5|uKXX$?{v}C=($`pz4^2>()B&u3X?TESmlWti zb23rkh{Yf)1d$gOnn5OCjO5Ax$&mwNwW9Ar-OMbul42`17xq^1hHZ5O>Vsjihw5Sc zMXZuETE4Zy4#TQ`P2PZ^DQfegu0T7bi}C12!2IC}AA+5CaPz~&GzkN1a==j1JFXKut;g2lv_G!CHrNJYlV5>Qh`Z(+Dg*}m?)ZJ~eM1d59Nl50?r z2k^<{JcdK7iodFWHRU}V$FUf9ig7Tt;4$@dtQXXAg(XZ^JQoFI->Xk=z0tv<)RDz( z6Pxii_G`j$y(n3B#2Z{v`6zg8O>00rwd8kD9E_wnzBSS~>Zq@3bcYIQK>##I30FmK zC3+;0ai>kR*@*ob-w{^L7#%iCvt$iQh+{(-+N5|RE2If#whYW=>-oMu-5E-SFTnd4 zF;oULH45iFKqk{R{MjIhbMy~BiZ z24Q(%7f6K7pDrMPwVg*BlmnC+$+wouxMdw$N|g|FlAGh(lkPbNW~f;2S(zmCTy!d= zYoFm8rBu6Qb&^VY$HQxCAiV&z z%b=U{K$w=6gc)cOHt@!zDTiN^l|gTbh_=S@xtmzV%U&Mv{I9Lz4WTw>XOHn(3nL6L zDmg*?@JzF6k{ClA&;bY~(H?=R6C~x7nW^*^bi{18Jdas#bv1Jb*s#IDF9WWwR~M~c zsa$`oDP{}2FP<>QEdXWN6}WuHz2O2G!ApgizaAqGbJ7#R*h>uV>rY!W3Ip`|!b>P0 z-Jd9M>buFD_yU%O;{-QBZOC zIUmYaC*Sk~9u|m!p}4~?)>a6C{L?OQ_w+Sl%u90rYOZAAry1`4$z4V32h{6Z>sgpU z?xqM?4B3Z!Qs2hh%UlF*iAn5j zYIBbSdB=H-&3P+fk|;Nfd-wD->Q1kieF zVuFn#f!x7_znw+j(9V$h`6ec-D9ZE7W~MdLRO-5wm=Bj`?Z)(vuk~_QC*oI3CmBgw z#2IgQbG9ze%T+GG9t?xgWkiY8RPpgEoaTjb=N$ksxAYu4?1PSp4Uc=KVRj&g;XWgi zTy%;UPxXrE*A&epZ7aB5oAgOZU5M!^Lh?gNTYB?01e|3ZR)5t}#&cL$xIH<*mh_5m zSnH4a{g5#tN)Tx@W_&4G+Jp9|PhetWE=rZ3?-J>2Xw6M(5N`y+-QA^>gI5B$JC&;n z!W(dydp2)%hR(yVX05LW&XgW1H208%PaYj# zhsgVq37E_zSC&k=srcB)jQZ57HC&xNOapRIx>N+QKYlZj@@m4guk$UCspV$=u5?hP zvwk?Dso_%ACyUZ%WRX|>=8@g0yRz^}b=4-0*~1@`&~LN*h}ktGa$kj6Wc`EI#xdOC z;G-|)U-}!>|6}VM+cS$6EnBf|+pIXL*tTukeq-CVZB%UAwrwX}r*Gdc{hWWWKdrs@ zoNJ89$EA$deXBPf_~Z8LL+i%p4hmiJdg8!s_1lUNwiH0lBO$VVsw1Zw<{NQC$}yd1{}@Q+6KLCj z7er*_iM7v90H9&b9zzxBW&~6tSg>nIzlTq(&E5xL{dx5Qw;!E4)e{!YE@_)daN~VaNRh$SZaIXfR zM-IlD+dyWUt?od#WssXQJ7xBZ3?2NUo)_6L7gX`rRg0rQO>T1C0tQ^;O9KY*hvN;r zaHXbS%l<}gRB8p{Jip#Vuk*f0{lN`l#^3D2us{9WFrKtsG1hB7e_M{j+!1*INeDii zgAp5dp!yCh4Y?fvxlwh?;rRT06uBI=jyUsp$`85UiQTVx9(|;9bMviFizSOrPfAAP zpJYg^>HP!NoT{o+69*88x6)m!mi!s7Jj%2D=KbMqDF(B^wSFWNa-Zdd$1ym)R)KzL6o7 zWSR3TlT8KKY>uPE zsi`SuWzwLgDumnsXXyr*66kz^!S3T>Us}C>vyQ2!-Q6ta@`CEw$C|k!VbyE5n2(o) zu-Cdn3fH^jf&i@dAV17OlKI(MYZWTuyF4e4{P`B@IS{nubHZt#Tv$TNFBk{A({7S{R!Cuv%yu9vJv|7m3a&M#K7uI~y?QsGUhPLf zY_2oKbSlk{axowDPvx4iUB1`XqCEpX6)m~zqoyGEyuq%eb%m1PJX?-;Qp&e!)wCs? zJczKr|JA~!-Z)pNr$w~Yp&)Pqh+-33Z(u2=sq@z7bde}h1;h(R`}4sbgJp#DKi>*1 zO!SZez!&91gB(X}hNXnE<7xVku$F#?Xx;fmVRDiAhWtiYYKU42$ts#zWSjlyV1GX+ z#Eh}Gk3XJUn(bQ5?${y_K6c=TBx|{(Zjk{5jDTd)IAKC6r4r!q5m4z_gGnL(ZSKAg zL34*9q9Xdgu#Ep6-N}PO3SW1;It2Zdv1BkN<94NNjtJ^^{r7i#yg+#VEv#J=opHur z%3g|m!59QD^=<`_?*0T;VfwHBIys$kZyho-mIaE9+3!6Azdd=b78Hypnf-oc z8~`|*xQWtfrJPf4^TqVGWzv!2_i+=`vKkN#{YaRTZRh}RolS^GdO93HFPto`?@@nU zhmu$q*fI?*Gqm8u{(QmuY6yPJUDJXbRo4tX!?163RH_W-3jafhcSSU=F;0GfCk7~Y z!&+_kBeSa;OmY2W=O;3eJ0*%4qMWv%mH|QG>d79nDkkF$HX-CSBzbdNbcDS&$AvN+ zuo&KNsbY4a-eRU~kb3Oiw?y7!I?X>}WnpW;Co3)ZF*SDHmG|Z{`+ZmKf@ULNqd?d2 z9IqdxH+ei1s}$-7<>4!$mJ6)qSaHB-o8P!)$nQFMV@#iI@rHLf+AI`f+{XUCdH}HB zLd>l6AZLwFHd$i-5Q{SL(m>i8O8of*7DOc4xVs=70bGCib>~iT)m`=erO=D=PpX1FXl8}88IQy6Z1!FAtcm=C0)xYdl zR@N3}yvjL-&J!qH@Y!=pdS5oj*MMrAgM)(SO4BJnsNJ!*hWA0i(Zoxg76F$4+Wie5 zE!Ugpr>(Azq1LXh;$j_lcpT;DFUeprGMRQs{#JPyYu@* zym&0h3e+qlrsSTCXN@j6>0*;%#Jswd#Z+Mo0hiu9nCD=)v6o=ZpxR?RD}1jD8>tTJ zLyfw`&51b@KL&q1wti3BCGIXa!xvCSpczA7(N+8uwz_|+@tl85!51nEBJM12!A zWl2`}iNZ?61LJR2R;8C(w~I}u>6eZd@7NMrI?9ZaD{db)&zgr^l9xMJdmVTC_>I#N z5WeK&QjOaM5iN;5mWkDP>B`21v;h>xP56}@k3ZxoDDt?63s?cgo?$!ikELC zZLFf$O{|iIF|UG`a)x+B!R6r`^;9>?StfvKXNl5P^gk&I0~cR8N| zAhDb(iRZ~|JSKx*rifgDmQ_GrL_?7iRSsf-2fdMY5nZTYASKEqfvi5F)ss4hjF()4 zdTeiG-4}66rgVPtR4?|z8Pm7~2=5g*(VW!C_;+O}$w#}2V-JiK4o`0mE;0RJ{3V$H zN9N=(_oE=xdV!0LtAL~^c+rUz^O$x&;Ju@tOWk?$=D2%dFBOQ>UFU1}Gx^(}-2_Ab zmwnbfs7Cb^Z7{U{W1daYdW?E}wW%}9ZDRBzUQs=yjqs|#ah>j~n#003{S>Rd{d)(+ zE0`nw%$V|yU(l_-MQxBfZiAw@E$RUN*#|O1uyAb`0$so7uXpa@$QxrhozqHA0LY}9 zn$H;OJ|%*BtvpLsY}~qUT^{?h3C>(C+K(Y3=!X8W6cT~o@2YOd3|V8iOKt|0j8Ezw z@DN({b8&LSwGA*1h?A_3;ubEjhQtRa1XC%aWseaEXr!1oj;DyGCB+R5dr`A0s~dC1 zfj^XFY+xIh8wkz-OO`YbD-fR(fSz4E(jNZi40ePAQp}#>LSq79JQNctD=U`eAFod> z;2!8F#S+IiO5{WnKpBY}Uj+_gQ**zO`J~ZgBpGl^tcQctjF@Fd9Qqxdd-506DRKR) z;fLjudCtoIPswBJPqFcHzdV#;pwCySb3F~`{O1o4vOpkJ_Bh);GILE8pp*cnc{p7d zv;R*6$AYwJL9Sxf4eIG((nJssxeanCU~mht>T*Q1Qu>(cUP(g2)T~81$nlDFF4+XKB`(-_ z&X!p7-zGrz4MWD?^I|Unz#a1n$#OD(AU%p=F%EPd_#3EBl;1v!;r&Qm>BR(4}Fs!LYON?>Y;+;} z0!W@aHS`*S_BqG$zD1|wKS061TNMh&C1L{1$%{B^zS{CzE;MhSX2S6_>I0Ok!4#vh zIF6nWD237=gqYY206esC$8qEXeO`-WKrW0U#NB#c7{Q2E!wznb zBebvn_Vf)gOTAv#yoc07NvIcxVe^$A#w)Y%{V+ml-a?~*@xLUOH!qmPYNr9}NWn9I zqR&n9YXPRCGY}aqbAW@%6lx>owQFCvV9$>e9XRc1g4L0tr&|nR+C|U&`+$d~;K>B! zn+w{9_JW157@qLoZec~}=Zt+42L15o z%qv52SuFhJS*|LSUQ3{EPO5ELap6e#dP?vcJf3z;SiMd9)tlprVB3PC>&geR`*C(vjL z!t(Fv^_Rcf7Lx^+ocbr*whuUqvW8O>6{S7_^sEIO%ze#8vSYCF#lKB$@@3ZU_=!#W zeUir`OS$bZv}Q~2Zm%n>RL^j<7p5`0Y=;o*=LDu|W;Zf(i({i;Czg&&O~{STj7>}j z(~cS>MC9ds2%`;|`eyqzdo2zv=h1wOUru_3W!}TEhI_;%49Bb8uxn7=q9UPa5?L&% zzy~79_A|1;sArP}9T%!Q#`+DiRT~aA2B4I1Fyl zHPr@;qZRRvFjPeE_TRn&I8qtRz_`K1HB~glR9YR(z_5W*6U@OB|Go7&Q%}sn@Bpj| zvWm*a^5#fM8k8d78}m#;L(45qO~u7ZT=Q%;!(9(oMQ5Ayzwsz#@?n!T_#fqs6=5L2 z1O&jJ%JMj>@zk!LYFPYoPCREkJ{@wo-{P~oo;`bRzPew$R#N1BKIDhkvP^?e1^2V6^UccNxo&Ug8(M~FxNx83N z9x5$j1mq4_-*iDjW7Zrj(xvjBdvV~nPT2<}0)G8?b@Yv&l#;Di8?b85deO$+m|{^h zlX}7Y*tuM#B;&9ao#{R$Enl?Yo!{=qU_8jRK2Z(^p?QLs$|By|E>Eq>ky@wS)ou=R z7%*0}5zwLYlT<1;SV9XvQz5!1BZa}z>(M=>y-B}9PqVHDol>EyGO&HzYPpUH`pCwu zy9-KZAMyH2T*b538KB9~i@%BxI{D$AKdDKV#H3{o*qwm;gM~|o-bitWh9&z#cpkl@ zL5F5EIHJx1(WSaE>+(dM2JP zHsyk*4;URxxpnCp!y5igbee#Tp9vHiht`zNzsSh)v{Ami77#5Yw~x*lGmO|x&W{5R zEmzbLeNA9Xgm)PGn zkomZ)vsk;VE{U1bnei~?u!UK-M`8ju8e#u~RXD=eImRSf#*_#PlRNSoWxb@GLn(va zdQwO}yI%`534k|!3-44fl+%K^O<$h`Ra}J4Wegns{j7&vIjpD-6yZoo-99)lo&zuPc8U{9?fV;ui(W#n`iIixx4~Xd8Le5>pT%$8SK9Og7MX#=^C?L**2$pMDegQSmL$A)$DJeaHMP{}R66WqXeD zO6kNz3g~B&ir`0dUOqHEvVeKiM2qQj{lr|iD+9)XjA$X5t!Uyj4zPuno@P`fwZ7aU0rXtex7 zjOiNWT~FW!iHKV^Zw)+%>1sRD)of@WYU=XRHvy3 zd$x*UR(>hosa4h&4i?)PSxLQuIq^e9(0~dxahNWcn8qTNSD`S$p!9Xemh)5M+ILJF%RRzhu5S3x4RV0e#&+r^_Cc2OxldEY!hLqvsM#PGXJ<#%8V@vG?dzCUBfG zS87Clzz^($EyGp+Q=WfTJ$*)p{HiP6PUFHBd7#k*i69zS&k)m3Go}`Ok`LrgnGw-H ztBD%XkW61}1^dVK*ygaY5me?O9m@4L|+dLUUSfsEATDl`#Cdtm0~0aV+N}_Li?=e zT|=Mz(|{wct5wTKBK6ur#7sO@_fw;#>cuQH18eF=FZPIWx0(y%^=)Z9v; zP<~s!h_cZc(W+Pb9jp#@!mOq@P(pq_A0oUrk2{oOxbQa-Wfa|Y6JTxHzcfwvgk%bb z2r40%bkr|8ZVz1t!lzy}ciL&qJAXW>3g!fQY2tY39fTPP;aW5@0%+<37fw05`|hZ3 zMtp<$hDXRW=x?sPJTMu;;{l>&%8O#E z--lIt6%kJ{WiSnJRe)7=hf{9jJF?27P2%RM02z=96i7jj@_YGK9UuKKhN24mp4gBAAh^%^Q=y7M9zdpKV5?~A1hdVZiKmpe zOTR3~u=aJkH;Tkg#viT`Z78jz;JnJFb6E>LqOPVv4OQKT$)BI5)7tPMAY~e%kyCr^7YuZd5>yW1&dk9h8nj4p z?VJpn#wGzgDuCa2hvP8$gM~J<#h|Af39+ZgjrnS<_xMXec^z6t-s?IG4rJ&qZ|4|NBUNOH-nybCM&78R0HgT+D5K}@RH?+A${j_5 zmei4peufv^EABpnM8+}yYc!x_B4SO|m#@5rk8Z7~hmR#h*j4S@12#WRNveV9D^R|Io>oAp9hCf*PEqVe6+( za1<)gUbWiJ$}XM5Ql^I{;Pa>d>QQm{;|WG34>R?BsVt+lq<_7kzoNha)68QvG+&o9-o z%e$Hes#vph?DkYt(Ui4aHl$HQ`8Ht)uLq=R_^$-=w~>@P8g#6UTixG%@k28aZg<@TOZ(TE?+NapEGs!K5(Zs zRWzqxJmH9kAq^S8VdKc5%0qO<%xHzi0>-_-<^~ait0|Fai^;~PeMVZce;wD6oF_}; zU1Ol+NqX?Gn4-~!?q-AKuD&ug!lkiWapB;wJj+ZF621g4M0N|4AW22IUT*DL9V~~K z*hMHj6`0e{IC!eXB@@C5u&+iuXx)5%32L3p4V;9xZ`)O@jY4r_`mJS^0A!^r zXPP%+dfO3HS*m-D>=ARqV|iBm#fXQ>3#09N3c0*Wo=Hwkzwg##-DmrsDoK{cnO{-Z zsGFXoXg+7>3M=F43AS$N(4Qpw5{4eTVq^O%{lbwXK{!Jl} zn(B>g#adcg)fG#r=S7k;sJ0pHOgCffl$aMh937Nr(*k4wd~>=!+ZQyPR`omLg0UKN48%uE)fBcS?N!4}+cJ z55_>ztUr#A_Lay#Q?YQey!NJIaM;`TDHRRn7ms{?9;IK+YOQJHrJ-euM0@@)o3c9n z$mMSuz&+w~7p1E)i|0{ohl9c{)qj0D3SB6mM9*8PL2GS=w{*-E0T^6IzB&b|5jx_1 z1uTC{@UgKQ^dq6gW>4lwu`;AqJn4_hZiTVo#B_#K4z)=rshf+zz)9?wsOs6fNe85U zwsI}GC~%mVFY;7_iO+`I6JTeG8=dfVGsL06dn`sFNYc>2OxFLAt@G5G39lcvFLSRm zKSi@V=nx+A^jBp4fa|0UGJB{lCk1M@NUOEXF>}y0fHEUKZgP2)yF|2EZ>6+8D}F4w zZkGe%6JHItKX^)^#_ag6>xw2DZyx$n*KF`P7q9A7ms5-7AI1%O^Ezu^(qlzkRS|N9`!qR~`~nrC`I%+WfP z$j9US3~6XU_g&JE6PM&)H76sI$IV1z2j=`1^d;URJ4~-`FW{@dOWMlH+Spg%AA^LV z>}l2{0p(?`o_xlMm^woKYguY}&Tx*^E9my^ag~HRc8XTI$4~E3bRmfP4UqX>)c`k? zzX&lXJx{wj8t7fhO4bY&?MCIwJ}15(EGf$oUu%SF0IcIP02DZDym>czXoLN%Guhq3 z=||)=>MtWkM^EA-GOnc|iw%2%UR}Rrq*q`feQN{X?loB4LWcc_%9-q@jbw8q=rdtY ze%&Yxi=cMb&T4d(FERE%)RF@Xb(g|3DceZ{T7h^HpAG0&Q}YKEBe3hxNj=FZs|0 z-~qnU+&b?$i?=x_e&g#5`}$M=1g5Pg9FEB4xW6znlZgkNy=^Jq+LU4JIK-=Q)ED?+ zqGD4euvIocoEIJwhxzX3z{u^2O*<;t-Y5 zEreBCOvXCwiuQIxl27vIlJXH{l~*g1I27>f92L9TjaKqltX$MNmopYdn6uOs+6ED* z-gVsrglSOso8=I>llQu;&Pd}VYF5vcEs;krEQ}pC6~#HB00OLJ9nU%XYq=2tyB@aT z{$h+NxILavn)j)_e(Z>T0$lTO&s}y|s*h6Q(U9YN6Rz1)B`dl1b38owrA~iJnN_pyxx!e{A^N0APYcs;t;n}YW*F9b z)B&hD;(K;)KJ=xa+MK$kw=M?GsQY)abrNGP+$2!~0WU_)5~H~3Xlq=3hFHO6s51#r zOf;Ki?a9?#2G=jIg3v&rU}rwBz>RlY4^JggKQ-rzp;j*KXeB7XHHUA|LNWHmHTpmL z2uW>kbj~glJ2bA&9^AbEF-&{7cOOJp33R)?_eqFAwprNdx;EPMha0ZX3Rn`6*J(2WIjUtu zU+YjJ$F2#>cmD{2yhRh;1W5py{&gUW#t3>{N&PE9Mn&koBXQtWfIG;2!|C<9lmask zeT|5+A#Py86P%W${XwDBIW&Q?H#DVwH=>oGwU&_OLHl)`7KaKKrno=yhjjn*>n`A` zTwMT2YRe23TnN+Jhu$a``Nl+|sdlN?s zJL6;nFsf9od@#IJM{_Xr)VO>wuGEG6|DbwoO#jZi{~y&uJz36iS<6Q1FhxyhgL&2^ zMvDF|s!)ZAiiSEd4_bsFkhJYKL*KPhEU5uPO`9TIFN`7+HSAbR=SjDMij30b8S;_9 zu=6L9{Ee)ACw1ow?(^TP=!NHobH-!Z2^`93IW%6JR0!SH9s((x9?ZiluEPkohz77T^7X1FtSg9pb zmub%Gbgivb84RSG-;HnUuL^Iw$EyouyZ49ypeZFp(5t;IvrvWk`l?=zunW?teu930 zj=sIW+*+fj1Q5ELwW*aQ3&oYHnG+5$I$?-{dA4!TLf>oKU|c?J?_b4833go#crVk# zy|`$$IBnfS_B_RZ+v2ERL)*LgIxSjna4v|>cpE)bfw93dN30EYj?kJOGcBaeMUgZH z{iF2^mKmQXVNGcplhVhcjIz>9{_XwZHD;v`N$W2&18Dx?dBlzW9*OCL9L$wzYf&%< zy|jkb=~R=VrmRLIlLjHo@sp6l0rkeYH2SN|0 z46h8w4ft*TkkKH`98=brvEdap7B!1fu6L_zniIjG^R zQPN2bSkgFUzco9+gg#$9q%64du#NA8SQI$RKeMPq zX`@W;lyyVL&cmjAVA20nu4f%Lczjgtb(!JW#HB zh8!#@Ej6D{E@BuXuGKHREKZYr6*@(on|tu%>6nEK`ubNhKjt}Ufcii`WRe_ksRu^#li%03Opp1w68oJ(B&Qg9DDck4erBq070MNQ@c>e+Fj%KmwVtSD{%@)hCqeZI~N=ipW zg(y#2?A)q-0dw&iK~uVNm#K&`b%#%OB?s3=sL6^ z2@l3Fa}>kHr5{CFA&NZ#elV(Il`gHPSed&7C5H`nyTJaz=CR@EZBfRf$6;pxYsnv! z#35tX-5Jxw>YXc>yEUY}a?Eg1+~Gvyy)R)OVqrhBI~AUbcEZqXY#DLQBrZi1FzvRs z6&EF8yEJ0#>4-YW3CPJs^ZbZ^sFbBf)s;sMT5h&Hc#26}cCLzF^p+286OYa^wMW-A z)n(y|Qdud37L3kJ)L?3~pRjn;uK8+G=~L4$UKV{;7Z`{=zFU_w|7#KMr=V{7wmOcN ztj70IoENMytLZoVT)R!GWjL!P9aJ-FIG&pqxfag-9QvxzofvdNuIgozhD z_7=EBYb_gX1N)L{STq`tDN;3hdSh02G)96J0wQUKe${9qx=e%xPYLEvmXH(LxnY^A zZfD7ZX}@ab{8I5XUZP~yP?-W4CT|)IYfiqU43D%-jwrF-qKl&?a!)d=n?0us23f{MYDBB0nm|6~mx17hBZ^B+3 zdzvhPOq2~b+mAZc4ySoMrALlz&a+8%rEuQ3U5cw$x~s`vm@{F8p;}BBWnoIOrnu&a z573jzpV;STVUU^=r6A?+6ipW|LEQErukzD4l0ET${>TPZ?sX$mi^<{wTseFzw1IQ< zR>#vWlN}2XxgY|ZStT=I8v4SF;0*gBn-XN0qi+(&I(cdmSFSH1d0=p3yuZm}goc_R z4q3%g#rY7998zdMgH1gh0W-wUf;c;#O^uJg>~nJ*NYRa}vL_^yE6&4u{_R(sPbZ-} zTlTtn_9efHQ@80u>Se<0nwTU+yPu& zytVX-7RxK_e;`f?MM5&>zAw``7ol#%*i|))-Gx>Zs=ce$TR~pCP@|^UQxf{laUi>K zf|p9alH(81vR7TIYj%;z2Z;)Wx^rS%4}Gsunu2iXsgBg^hYf|QT^Qf|u`-!9aln(! zL+bz`8AZhv#!Vi)D@E#@4NhG3vL9<*YVYeZL_x$C-!V7Ko#NF>xk{s=r*XJ8HlO<0 z2r~d5TPj6}OEmOjOc863fAk^-yla%_^Oq`^(G&nskllnpPv&q{)Rq+I=Z?3!-NEBM zkz{|n=ATo)wNlBgn5ST$Qdv?~*$BfjjbWUflYP`L9J1r*JM@EphK;x#a@d*Dg3Pi zn=S^7Zu>2DW^xBeZ}R5SA}d8*nH}yNcQDAe7!_uIZh^LrL5tB2VL4_&hoF)DbKM{L zrx9MfVQhWHH&LJoOMt-VUO1Bax&QbVTCOSgI2>zV}PE_vO%a)IUWw! zKtPMDq@$wTuhV0*1HnKb2#I{T_Ww$u)3+<+7SVpANj1#&@m`*lY`o=d{`usjM1r|m zME(5@_gKpQ-Dv(f)p7E`gWxG7ffDX$9xUtri(vKuMar6E%r~>cM!}8=oy;b)N?k0U zQ8T77&sE_!7Js5ZA)qNSAJ%q>(tifvFms}4;8*8Y>z8$k%1SCqGe3WjsI(9$*=nYw z2v3;k2TKqf=*Ct|eW3(Lm2S^?r%&1Da5L!#nW|E(BM^}!8STn$j}(VrLrU8LlOW~j zEU#H!R>^Vb1U%k%PYO>ZJW)s#GU{0T!Mk($^hN`-P2*R%S&G0PJAX-*&lL<{V^b?) zih9Ws%?s_$SKtH%bIoQwX15voItVI<%eJCo~?Mfs1{OXfTdq5p+mH=T6R zF0ChepoA>igJGD5Kd?j%d2UH%pAC4%*qqYC04qm(?Xy&eue1mhyr`#DVHLp7kFWoR zvaLfWNByIH$Bp{@+r+|M(e+IJ1Yk>wIr<-Du0J|qn(c_UXTbog7Y!ijOXVUvZ;Omo zg@mCjX*|zOFr@YEOlojF}LH!BUR;Rx4%oXS@#T@)gE^#;T^Du2AqJ1sCI+dTVlU9_w^V za^msZ0SeF(L2+Ajuqk(N6i+I!Og|$eajk<3vRR$;Vca0;tMn37u^+ookUAxA+_^N0wBgpP#psl=&r#W5c6zsVDpDyb_?8$eJf1gJ{;_-G9LA&;p~zkWcPk zH_Wn;ZRFrEGux^2chRzrHdtFnmu#g&z>dI;#}xQnhvk;zaisqO( z6;etxR!e9yTnD@RJzg;FfubyP3^~%Q2*Fk$^pA2cyvn2H?snY*55z5}2^J?oxB-Il z$UMdt(Q*SjQ5?+0 zvw_?PNW(|~vkI|#;OrAm8fpd&SbCYG*-Ttk+0+qD9bKMyqS`y;Xt86yGkZTbMI|mi zTWPwB6f?h)-2!Nf=9TYw4@L>U`?Z+v5z8g@S=_l+3`gNea!$uufSP-nPxBF~-W5Q6 zT;5_krSKFD_x^=8cGLlb8q$fqe%d~>(RobGqka#b-W)A%Mu_2YcSF$RrcB)$cn&f2 zyPX%K;`9-#P`fx-vF!Limi{HSal6Ehy<5I`i+B2qA^YsIn`<$n^M$F~HIei;HGdlB z@vkMhx+v{&?i|4!P(OdjEwwp5wy? z*qcug-t|7-_E_B_jntfUXp5A)OnnLw$Hr?Kt}^!il@fi3#tR}kn*7(+CjePrC?vO| zxrTgF>PPWu9E!_m>T)S`fN&`FWBHind!g#Obe128@fE`y(yt2{biF!`z^Y=Q>({ol z!$VH}a>JQ(=UL%q!#|g3H0El;sxjzIobBTyltNSxp1r0t?8 z?z-O1Ys()rSKU%Wqa-s2g8=Kz<6>VgRIh7#It{4AzBQu$0C;;Ju8Nd)<@v=MJ1M$C^bGQjuPY20PaZ4h}! zJh35#+yp5o{q>r6(40RzrHs_>rHV`n46w#dj9aR}@jgJBIEU8~&1h_lAar?lP&?$y z9$zquP?8qs8agzX+jhByWvH+KJUvD~BodGbw*J&+a`Stu+OKLd3%W+_Yy|HUICNKe z0D+RGDhZb_O2F_U4M3iB|B-NBzF6zOV4q)IzW++3X{jNPS*jpp8DKb(BXcLa=&}+p zWis~HS%=HsA+AnKg3BBtwsvyG;=u_mc!&sxQd97} z72+~%-P&mY{bR4G27&_XldXLg_oRiGr^x*Dzeg)#|-(}CLRIANspCK_7$vgu4zwi?g&_-hm*v8 z6MjiXAiC}jS-^;SrG%P9&uB8^hLAt9V~QSBKE=GF5v)DRJqPZh$LHh=qunQH8vA=O zgl9hHlm+tX^S_^HLhp%_qlIt5;_6mztkJ%V?PG3;dC30YZ;BcMy3eUe zkeu4|6v|*D*LQBtq}uz^tAliZz}uULL^wGk3KS(z@c@2Gk#m=u&3cXu+<7Bi;bwLb zBvDvD23zH-ZPPsI+XAG6j&}hP7Z*Dn=jDVA(H)n4=_Hp%6x1!`n;jDABKOBgsa?n|I;tne&iMmgldpFm%w|x5Zm0gnpY^Qg<5=}heHp$4R*GbUq^20_conimf z$3%$Lr1kd*v#KHR_X%99S_H85O`eA<^`wF9WwC22CSO#An_1SVrf zfkYf-G4QdNG&{o9CW8X_c)$XEPx3{Btw$^)<$$@Sl?pne2cvNsW~m4!G`D(<5PHCS zm~@|4=U8iW$&zQGY&+w?s=xv_zKP;zcjgh!;%=#WTY~ry!gGf*+WkvD^M^jtijqhY zb&Jjm1BYO(8Tpo=XgB5@(9|8bCO%3iwv_XrT2TP}mpi+Mr*MOjv!LR=cUXzji}Ty} zF#zygUG%G1&({~W`)GFa9EOW*g1kDbp$}7MYq5ZD^SbtBMj4lTGrhcYX#K8c>l4oP znwkviA6pUrD6Wvw5zKixkumtYt?WKELz_70_U}cAoGjk>#F8aZ;zZG`DT3bs$utQ5fZ{u;~!U1u*>uzR*Ajns!WQFE>1@H;Axm&ZAO(JQ? zwsKb;4e`9l+NtNz#$~W`j4R@`aS{i&2~vjuDZU}7!86D%d{rE?AZ$6mNOcw`4WKf1 zV^fZZf%8%uyh7tyHrN3vX!^~!?yGZ&x1>Ha@U?JKi#LyfR}uPv3r`W*mkFzPRyWz@ zpeE$xqhh7e&_|~>x9q7Y7P?-`%*|F485zA^oy7?^9Ds2$a*hm5sFqdT@HlQ{3nKJ`RjX#T0Bm1Mu;?t1GKW*^}>>WRcP)tynS%6)qy;l@jXk+>9x& zN*)RmLr30}SFJ+qWb#(X8HNi(?vG)BuKGI!Z$&~&$l}{pCMD8wR?Xp(eW4zkwj_Uj zTu)r=5Rff>L70Ca7^nS!-EQB^|F;9;GmKR@=r-g z>8|Utv6$%UN#Q+>Oi`4yqj3%+MlnG=*r3eZNT@e<2p@|Y+a!=m`Esb;roG<(=IA;6 zbo4#>c>9`u*;RKy0)!mAj#q54COfVjL#J0Yc>g9k((P-164?ZgkGS!2yr?%CTYV?1 z?e6ux=kBm!{dmTf4m#-It1OpyOKYN&nc_MtiC{0fNl8tWaBHS%rh|h{RxX)krP)B^ zGFTx0Qrwy?SWMqexVE%PRHajOmaI(5mb6K2xJx$={@W!~3sABwW^yT1tn6p38dR>f zV7gw7F<@2aR1LoBJ6x5tW(@%~tOD&&R#s-Ae;0qWyL;X*lyg|?^Qp|)m)piYMw>hw zu*1A|0q^+{+Wmth=44pUz6&FWID{wBwRFhBMbJL8oS2p9g_3n?j-K8x07>wrjT7SNde>kusp;H$E(_n#lLd-(xDQ2F& zHeyR)JG!6&1Lzl2|8&5r4d}X|bw%Y0E`+jCHwzE@c#5%Ec&*)3RyMFRdwt=EOuP9E zG2krM>UUq!C4Pw3%zsl!?V@!X z+qP}1W81cqj@5DUb!^+Vt&VNmw(XO@PVK5wr}o{te6Qxa)|_KLL%;pe{ID}ZWnzWP zh|h3!pRH}QxPG|@s7l|~vJ}7s+D~Oda5C4Fer8?0dR4dglbKQ|Iy^Q=fGVdIx%iGQ zAJAi(-s#RTjuEp-l&Sus% zmqi1%Jp&z@o5m5KTJ?y%mSw7Ub zC-AFMYx9>B59sfQA;4uk$_;6L6}wV>Ib#i}jA*}DU0>(&J3Ucd$>3c2M-jeunBI{i zc4M%R-+wF9t+aVB4>P3fkRzT!w*|~@`QF^86~wEFzD?|BVe=D4iRbL2&&K!F2OY+n4Vs;z%cSjuqhmc0 zp4oa4{BLFTzpD9PRb^)3{vj25eyXaru%v>7LJL+eIOu;Y0$U0}AGkjtJtzXy2b9v| zl@Tt@tbG0087v+)8?dOBUZ7x(ghU;2 zXB|%yn?R!oy*1iMO`0&KNY(1AH2z3koNyV+(Ha3`BKc$qE@_Eru;K{&oMM5+bgvclq+zIj0xD0zBl8%fBrYu*}QJmK){LAV?w%B;}u z8P>G_HZ2`u1w@#7SCYVn9QzFqP*creB`gIX7ECci$R2VgVl*S7_KcBKq)U@u& z>%UVFS8(88{ip%_Wn9^&zp*Z70ep?Kc3^ZtYLUj2{5~E zk`X3BY&x}(mmEtOq?|pbk|%Uny1|s6HS*WgLx5)w{^fgoc(c@#g+nv@4?B=p-gJS~ zEfWyYApc=vuf~CPj1vwUei+FP+-}A(2S=rSSnx!iVof*I>lq6F2+#LX z1XnZbkS$)ye4@WxAdPVb{F_U5Cach{uBoIcqhhvWMe8>g(#X=$xzFefIj`60V*{)` z_~S`=F;z~8w+yGJ`SwoMz26^JM#|mBg2gS~E^^=3b4V!jfOJ0$s-65f?wd@G;lKYK z?|-J=4~FzG5}NJM)(Oh6-2o{>+GkW&;vFU$7DXj!*cWWLCoOJ0jd$Gz=T$m*VgKvb zX>F%#Vi0cYAw)@}(oyKUk=xVJzkI-Co3gN(%V`J^S$vtGc+8+u8vWp13%CZXQP9pI za2l~M`g1~2)qA8l4@H?`CPU1wb6#zEB^Zr$;hRqh%C9mgh7d=b9UY5=45#Oj-C>mG z=`yHK(^ZBOB+sr8oJK~yYT7ti@T5e^-Q3?^RUZwRjb=TJ1x|NoYUe8C|Goj4w-(}$ zfVXdQa<4%X?x2q_^kcQUmfsb<7TmHLrpT09qhz|+`7EB5xYxy)`F05byh?my-xnG4 znBB=dB1?B$b#1?eW>l;TY;SLuEE+e36mT8z?3CUHo!8!0Y7q+xnkI31qO}lml0yaR zew-?+u#H_*WlUK>w5nK)IA8$lzk5U7l7eIc?+?V%J>xGry?|Qt%Z;{mD;{$19@Os~ z&B=Y}cfF_nA?urthBYYfI*#0N52;(xp|Ro9;a<--+;`)Bxr0&5MpC>XlM#R(&lRb@bm4<5 z{7J&{F=f};HoH{}z4CeFG5j><>c6!0GK_R{mzG)#yf9W+vsJ?gDmueKmCa} zN0mcILu<_$kFf z;bih7$+YLBD??>P*4;7E?J}2d7RMK))vdYL7 z1mWS{Iih!LHTme|EP45pl^wQ$gM$gCZ{S+e#>4;lWv37~fug05kNvQM3R<$_s*){+ zW8jCtKhK{3l!X5;kW=LWt*NrS^b|(TEm5T1R06J};E;{pgutb9#*1O0gcK*$#~TsL z6huY~4GdyLA(-k9_cORLvBj^bT3X6$T2!xC^psg&_c=M*dcOp<^t#@DdhfpejzS!} z&rIl?(!PGLcB>-I*FO^p6D0wxKdvv+tv4Fy-)m!1?z%yK!6Sd06Z)pQGcJ8wUCB0< zc{!V|8~W}Lp$Q<#`39jxh>okRzYO@6zddCWDm2U0+-c(Tnv)mN^0GqdK!c zE*tdx-sS?sf}PlbBU6vOgqXI!>#Q`q}kINRL{S)~Si=z>ZKKZ~shR(y{LhoW+M z;>y(v5LVReDe2Nt`9C3z$x6`+mSaKM@^S@3inwLy3z}A_P4VeMQ3V_-6{Rhuw+k3n z?Cc5Yg0@9VitD9K3+oFuRwzwb+7jF<&ZWzxU#e*AIi6YdZ=v;2ZJXKa#R)8sR-nV$El=daWS^ zaFjU?Dl|R~I>*lp)<52MmV51@Hd(z6XM9B{;cR_H?!;d+KDTtAik~y4gQbEU`;*}! zaGwzE$la9Rq8|XPAuV`4yR#1G-J&}6@StCdl#Xe@m02VerTc!V-w0+6LMVf&T)bF} zkVo{R@_)pu5^D-^=VTGva4H5g4xzGZVVC?fvg4BGIRC)d|JH!MtWu{t=ri+9GVSRe z@ImMTQ9rOcOu>wJ8O^HDGK;2R#V{7iibsj~>>yYheGUS=Gb}K%yv25b;N&7mvt5^A z(_ZFp+6R#^ox$;l&>COHN;%;u$jZ!=3;rgoMHc45-mDaWrk{cHY^^Y^d_Qfu)WHrMJ`^~Tgul~gzadHHI z;3G0|ErLzA5mcVrej{CzdC3Is$`}D_%%(u@-q;5a7dK$1xQ^X3_Dlg$kEgU>ME|{> z3-82M5@=ebDj0!QmH+*9IvPQEaG^Q9yCTr$gc~MjVg~Ucqj;^b+m~Vs zw+aE6uqsKg#B=&L@5yl7$kQnF_U{fP_2oD3cs}w-)$1I7750S`9F09xNGDR29s^mY zk_r~gY;38tyzefcNP8<^sE}M}y>A_H6 z3Nql_GX9*kUDx*4=%4JPMu!(m%Zk`L_D1yxw(nfH+uvanwbKv*%#)!HS6%y|RixZ-~JR>^#*63p@j+(K{Y&D`;>(Io9#Zz(b|5hpl=>vmHKq=(gcl|bzj z`cl8ZXY%$ZQSU})JaQp>-mjzCfENB<?6>R+ zktO(m$A@3pE2`e1(t%)|Ux&R~9t`I%OMC@F?h%{d-Bh^GDD2M&vK@pF&Ilp^BzA2t zTyJUv2@!rTKrLGTZAdOyq>MgZ?APKtGq}(=%iDw?*nz(eZil>FLq7zTMZ84A@T~;* z;DmwHst%h~Bew4RxGP9HwJX7hO@-iz9Ht|9Xkjk>rks>J5aTA#S5#vVHxy?$WPn8 z2k~(<*pT`e1MT5hf7$}?ca;m?fEt9(*rB;A8KB`ZXiz5{DF1^>*?}+RCYLb-3h>bi zSQ_Ii8DJn0cW(b#{dP)#2~cG6H4bU{_gAgriwo+5QlP`ANis=~QB3C)upJ^i)44(; z9zKO_6E7v!N|oE8JO`0%O3$SC2nf5zOE;K#lqt>>g?M_6)gn98Ifb!2CnB~}C!A^R zLkPY0$VYI1Pj;mzv3T}qy{Le)J~ky8#s60?ywTR`OrQfK?oltDl-g&jb7B9-!yayB zpWYoIJ8biYfDKbYB4cI)Ksd{^zzG}acpIBp8b`4!wc1(sZT?=suP}3N zdGpe}>zmOcad8{3UwF$U6j)PKa*^!%`jywna6r5A(~Cpn1aUqGY_Rnaj^1HAZ~hxQ z?<>3=3?vcrKhjTi54Wtg$JSnna$Zzp7JwP7C5K@8ZoT~l;Dm4U)Y_LFezWFtneIF@VmYo!ntn&rjWX54jY#jS)|2AGiLSKC zU8O8(;~vt=3gI&j$lr9QLGJoN_0Xq>u2%55<87)*2_@L@+nis1eUSfxkm(j*l?)Q! z@_j>#%8XIt!j-XzL|*WY9mvC^d47$X9+3Fb{EY>zEu83!xAs@J7EP}ITJm-V!1VwH zZLm$s+AW#g*Jg{(KfE>R9PC&NDQ=_P{-@3PAl=R%rt?h<5GNTfEouMoGgHY!slonb z-+|==P4Q+lEBe7hFvpDWXv-VtRxB01{aP{ff-r_wn(j%&<uiCJftXz#Ax~CP zDY7WPw)7(wu-q#Lo5>M*$i!#hiVJw+4OeN$yM*QfF-wmi3#WRsRcoF>dvClf4mDra z$dB+J6+Y$}I00(!%lAMzm~s3bZBTlyQw_h3n7SiriZ}oC5IKpjU(Jn|NYRK zSzFw}hYdGM3`Jg~f}PCPNVe7kP}as)^J7q6v+WESUUQJYPXLQ~0R`M!K$Gc#T$c%2 zGi;Rs1V_|h8D7+Ov38BSpmGE=6v)h`nOg5~OvuPA(v=BS(nZ7)(>uFw5Ja&eB2e>GxN{k3q`Bc7v}Wx@so_dq>jCt z&p*Fe`@w)QB|l?&L`q4aZc6Y~TM(vPxsprl-DO*skweTSqy#$~eST zN%+$Iaqc8}f@<{ww4*5S`V*1NNSr(e74uH=NkvjAps0{i%*r1$orEZIr`onk#3{+y zStd+uSHG3CLJJXW+I@?-%SrN8&)jAJlqOPkp}UuOT;mIg9Q>lHLz#;BB}pPMvuC;^ zRPkR^1h77D3V3%gE4#GoBbGC$QZYPkBBiw7-#KDe_s)^T`GIIBf#6xS2v@B!Yrnc` z+RR5*^9VOh4;|us!eLCVg}*H z;sx8LG!xAi7XM#H>|L7`k>b@?e%KoYd?!=uOvd^=PsabB( zkcRa?_i6Y$3SrWf+x#0I?bcJI(o(+eqQIY`t2y>7n;CP@u!&&{aBn?HajMxL0f}9&P;)3rKB@TmD?>96pps4yg8&Ch z6UVBGfwto4M)P0tONY!5T0Y~^F}eLxTGKF5PHTg!GPb8$`EG3@<~-jB>CiwNTaL`h zz05#}D^J~^>5Al%<-w?~x2*b9SJit&3qcMY*79m}0cK-6PU4*TvoQG?;e$t`lFy7n zMcHF8{KOr81U{xQ3lldvz!7KfV!y)!g?upMluDAt%(AH%j-iB!_-khr_S~Mb5j7j` z<-@)^Gl~~Ooqp42h~7(W3$9`F-(IYYLu8xN+gwU0AGf0{LrKgMjohXxb2nDw3^;B1 z8pG*;KVJ6s5&7w_rHxei9M(Y74Umqz))+G8I$IYuqSo zS3!^xp;x~*HXD2pVRmLo{R4XR@xTIuz`+uO)Sh>G>Tn@*{zL>OBFN%*=%RxZGgVW- z(hz6Ko(}fADDH^A7ZNfriX;T}tC;45+LkmklZz_;3KJP9 z;-yApd6MyW;rWgMYGD}vDiUW?M%tM>YhuLG4cK) zNzRn2pp(}1BFHGV(dcC%U_Tu`DvBl=xA5rh%bO<%-XK2_R2`Jv|C_~%yqGg#RTF0t zE@mjmUG9yG1W1)DNt$rd;wo{!e`?T&)SPul;IU(mf)I&zXmN2Wm`Dd}hDJvz$oBO+ z0)Fuaeu*#(6gODn?ow&8O)?IAK)%hL26R|&SZ`e3ld>El4U?4~)Z00w{6UQvfN3*Wqj||6CUOs32|f|lpwC+PKEl+Z+19tc%4tmN&LXc6 zP_x13Qp}RV>aP0A25i!n>L&4~KSQAnyzb+j3!u-@nH!SV#M|kb?|ga*u@DeXm~SI! z3TJXdpd>eZWz@VcD`=~_F@D&DS6agdVOV1)-vx`20*irmH_?d1-x@s+J1GiS>UslH zjdN))YepWt`wP0}7Wj+b?_xpMpzz|XQAXg$UqQK6t-yKUsvzp@+p^?xU{Pnur|onb z0DxTssp?EZP_+#KGg8X^gW6T1oPenSu|sBzlW@!Dy@lZO@J*EvVaYPSn)}#FrDDVj z1oPh0i9{-xo*H0IMHzh+_;-#S$>PEOHA;{}9odsmtaemG0k9>f?_ ztrtu}-?a2p+$NicGK`3WLn%*Ii*MVm7tml@pe@k~TWq6J=FpkKBT9pM`XCpwaxgq*j&+)+v@Gz07-#%XWG#tz~u{8$b$LNYTwNlVv|tf5nGA5%vgPGpb> z5+3-%WaP0VIkF_`;ERC(8?!4lg0Dnf=%X{ShlwjsxLebzLay2RuGm&XTt6}22!PEr z3Xzz>c!kVyU#x^iN*3`{tg*i=$-}9bB>*_bE(F8% zbpH7~-nn-RESR7fS{qdW z1!0!&V)0N-hS=xRGNC8-v&bD56DQK=OKn$VA{duZrodY4yclI`M(OtoeuGAcT?y}$ z0O92>dL0B`n@@ZZj4`)}4d_ABI9$*ng$W=HILMC9krOk1xQp2?(3lx#%`u8QkJcpI z)@K)8mcpgN$ZO$8Dp2N65DO?iCPNzf>tp2VYnQhXYZ$w?n=*4Vt_6_*40Gv>{>m&( zPBzBPJHm`9w{*C2Fyj0yK`}%VN(|)dtw2e1 zVgalTn+;>&z!|bRTF&%y@oM4QquPhlGU47gaQ}&xQ_%fjV%3)Qo=|~xY7UJf{YLkq zE}ZS>r|K zsp8V|Zv6bj1!JNwE8>rIvvF~dG*UG)Q!;w=$}YiUmf`t8!V4as`HLPC_hKIti;u(d z2;HpJz3%1{i`MCHU&l~eqo$9(S=k2rI)P4`pMB8MzlKvi0)Tb>OZ$2e`jp((N(m`) zU2R>Con<9lB1Lb{7Un^T)}JpDugjV$lTWN3j+oaU?@bjR8aTp*KsXd~%5}FLN-~l{ za+eY49)sfKcx7K>YEx-Bvu|Yt8~7Bb?iFJ&G-NeGsA#<~K+NP0bVmAm>bSW&Cqiw6 zVP|g@4tF3c2w44^gK<_mT$P)=A2ME_M8Io)ZHby8{A2!roi5c*5%D}En*y+t3Q$lAJiuYNGNS$w-n|OAT#XfBzPC=T|K|yXc zlQKo}g=b9JU)|}W>ZvM1k3Mv`WXr8159R*Txoo~O3E;!>mIZ31$svy({2k|9j-o6y zAC+`5ZJ+N;7{qqrgTN@GpZ&C5cOPkJA#XtvA#vgRG|jy4T7VpXymE?XiLBO~H^#vN zoeQWR9_Qyq$YG74%t_gU`hIK-KMH65v}`Re!I5)en0W%1>MMR8(zlzKt6qa=!<;Y3Y&zCG+vlX{rODK zVPE5k&PK?Ub8?pH+dSv$Hn6(ExJgml>IPEZXje>{!2;%>J=~l)t7P6l&yv5oU|QrX z0O8$js+zDNJI1QBi5GIUKubN^sadteC^E@pfxUSSI+IR_#MgCI8pq6GNF%sjiY1Adk6mmpL?`3iq+ zhrjY!Qsa^-4O7~N#>h$OitEAzq)1H+0tofl%nGgqgw<+O|%0FNTRwDxZlGOKvDT*E!qyuasK4Tf2-8kq6P5ylT# zl=X&+rz$K=5pS1bv_RaT>DoV*@?A?y?R0tfMmRI=dhc{r4BI1J%HSxF4Z_SQO(%%w zcOXRXhi2$hI1%lkdu5$jMcQj22Nh?L3B;>|72}c6WNS9ZFubmfLt9c2z#%KNIa)*; zRN6uQm&u$VyhG>vr#V=srsnC^d2MuY$_+}hjKAMkOX{pL$^&%bP#>n#f(0##y&!0b zHwh$#P*$PxnJV_^+>aWI|3$7R1Skfsx7wY}SENc>j$BTzNM?+MuQgh+1ybQKe4%O&sTfB|8sF zBF%%Dv=a`3mP+62CEM7v9rdN#onnr;{?t^szP2^e;**yD1&g>w;&c5!6G9`~|4#p* zJpXql_}__>iJL2h<^-GtLPK0aR9L#j_yipKKd6Tz#qRVc1|J4oR7Vk3IZ2SDK5zic z5*ak`H{5P59E>D&Dila?pr(p8L`5!C$!}hZqs)7s z?(3OE)R_F=YmfJ_GfhIfumPk6ANq?8ZE0-Bz5C|3-DE`s@<+EI78xN8!>a$b@FClc zayY5^0jHWnpqS3?1>fw?UnD5wr#tymiRNO>uwqS5BV0THM`JdNjU zI);{hA;3c7VyrsRD(3n7yD~5Obl(ZE>oCZ6H#90iMv<)9_wtE3HeQ4FZ})H=e3Z{y zd)eEvc%${#CtS=)A4Np`H;6&`EIZDF+|55}=J$Cb^q=eUljL0k853lqqA^*Ww=VBR zcg~-cgT~(kUw_pm$BwkY7QoC_$6YL`o(R0WS>B%~ch748G&c$P1w; zaRDf)*wwNt%6JrgA+7Lq>%m^rCy~z{zz4_^CxG{&V2G|t5@wVpIbeb9t-RdJ5kKv} zgKYZWfCx@^o#A|Ybz7b?11nB;GpnCN?>`i4Mw(j*Rc(r@iCcc&&39oCjH0@=?-p3Q z*r}X>uPNlVUe+r$XT})`k)eTn#&CnolQVw4U1n|k?ySC#V}HSdg7vjskdbaejp5OGtXjt7?g4RHC zrJPzG=?K)iXrVfi&|8cv_%n=ftnFI+nDsf#2TAPq=cI z1PkJQ{w*8t_3TQ4^(^P8DXUk7qal!8L7te;KvFB+543JS$;!d8xT?)^o@jOvR_&z- zTmD`VFLW{TJ+it05dI@mJt{5HcbP@@kqtvBKc0 zz|caB!i*w}qKslG_Wy;0_)mhNq*&g7%cgYXfup31+<;sD015xU%)7_~(gjtchPM- zKW;P`cIp?ncu3%Wa|=G%J}l06|D0W(`d92$T#Z+e!v|3u=}#C*(TX=UROPh3Fvm(-pbRKp%z`N&T%(yFUL!^#Gh@=95<}@a)i%(UM zCFMYd4Lu!jHD;{~SP`ZpF-N)z1g%R=mAW8nMv)2C8er&))0B2ck`Lsoi%b={pvVmS zGXQ4HRTrKrsfkL6Od3i&VAYq5CFKw%H9*xD{*sz18%eQ*a*bpH6@NpvMLvY$?N2;} zj8>Op7n|6#jHj{C>ZnVyCz&?}s44Pr8Sb;eCZx5a4IThfuNjWtbM;bQ6o+!{ zEI)B)pb0wLb%2uN&AMw(=6P(u5yvk-dc&L*u~oh7dQa&|w9YQ8!Y-JT2b7C1y$1`^-=LPi(fznE=qZaxknmI?$5x(v!@6Ik?B$w|j`7U_I~x8t0s=_LlQyEz z-us@@E^o{@2r~dkhh6$l5uPGyZUH34QBxwxRgQHR7E6R3nfESVGB6f{3_?DZALRCe;B80W7gQxQBSh#JcflsTg9^ zqlrVM4Mv=Uozz9h8qz}aBTASS#~A*~uPx(Fq*Ek-%Wnp3V^#NdyS#djfus-z#dwzzU5^*m3~(b{d{G2m@a}wK zV6lHR_e-wDFH0cw9q4jvK$N#*=R&m6{)t(_(sC3@b!udVu~1PGFuqR3_3@yblkFnZf2jYIMI6Xfa1$~TwDEWJGY-VH zxZ8?x(5e<_*``VgafXmLIsdm4?wpv)e>Xnb8oyNC=N@LyL<$&Z5A{U~BJQq)|q z+t-2A9xpF&q!+Ihy8hG$ZmY5y=HX)hjmyT9PV1we6GFs47AHh|c4Ry!=CkzG>n5AH zfGZ^<_P9O$jPT{eSg3zKOK0$(SIzl>F3kWlnySJgh+OgCg8M%?v};akf1X5edAlcV0;B|clUV>i z@q*cD3n5y|#}9D4Ng{i;oMyMS`-9sgM!SuF7mW^n5uJS2+I!&$2+Y;_EIS5(B)gl9=dia}|uT__ddC^0zj zx?tMfQUy$a;R2p9itSz*Y{L{{e^DPRy0=vZkPt0^0!{W;+dkM;uA8jS{}n2N{lSl> z-W2e<<)k1<+9?-SgR!vlQK5)$@>q`ZwIe91$$(i(w%=hQ5XNWLqa81g7zwE6`x8?U zv$S0zBji&{#?H(XjjVB1<2Hzp^|$o|zY*IuSY)PS2I7w3`~B4jSyCPr+z3WJTKr#$ zB*=pQA)u$s;i%idN8_;yE~?tJq0d@~AQvu|IS@JMd?%BWH+UZkRFTV8NIu)t`D8W~ z^{@X1=Jc*6m-lGR$k@GNB@y7St-=V#2l?73j!ZOeaZDbgKCjQ|(4brdCXY?C!S(&5 z)({xp8w{Rb)jJA?;kmjXr?v`swBXn-rD#E%b8+6T<%2!zjyqS`yHu3lK2s?<3y1N# zdMwyRPkq1AH1#5S`(5v0K~6x%&PvxtOj&O(`eQE-9GZX+rJf>;lOUj1aEzC&XadK1 z>_M=rJu z7RUsI?r8wH&qhS@MLys%MO3>sf)kq37qO&g(BT$^3wE`Bq`W&~NhbS_*aJhZuQhig zwrP_nO3*r!PsP#Z-jO~?WRf~0IGgNRSDBqTjl?z+Low+OIlTcLic(ii|;@Ay;g&|E;0}Mj<<30dUpz<3T-Xd(DBbig4*g^72fks()aF zCH48m`g8wOyouCyhGA$yU_pV{-KsuGy7zX%q0})_@E`zvJ;YUtRVyx3{lJoCV%;4* zjt&=uo!chDE?^+$hzIiokR6_$?d?;Ur#vTDzBjp$6~gDIl(C@v4_ginZ?f+udieCi zQ>JxCF!=%CJk`EczTt7X1HZ$lu_Nsd36LV7t+HIY94stE<1+d1R%4%Nsu?~jz-lvK zkijNgpOygnk;ckwr$NGkMmZ97_pi!CR@C&Pwj(C|@U1{>sgCLk9}W*LlFp*k=X$u= zd@T=(Q^~?JLW@moygupJR7%WNMxEp-*pI1sWSwg9y;UFGizU9J-`zAab8Y9jF}ti! zR)me$zqU9XbwNJhvrDF%IkJFrl(wsULxWi?=LG;u(cKG#giae}9j5T5N*uvzMp&SX zJ8=Fq{TwH(NU`FB=nV_ru&mLr9qU;Jdg>!HZ z5VNY^5noy-OrlEIW=O=HJ&}?uk`dr z%8LMJsY}2XBFXlVZsn?}e_`VdetM$z=Vg{GYyO$OA{-7cK~qO}P8^j)Wm~Di6a%^o zopTNjC_lJX2^j>7wyBVKL>DonGE=zLYhIdnmzeV1=Q?mpSI6x7G6qEaUOrl{w0PaJ zj=xS^Q*McQ>`9mBs2|~8(VsV1mw;AnDl|YuP@k2fh{&HmpaHrwV5~*L1ZP5|^#0o> zQ!~#yK66m$te4w?Rh(^}Eu2A`$w=vat#0k+!6qHt*6Q?*_7Aj@rZM=I(rvgpv5uq+ zsJdb04?unk)dB0vo*u_3VW~dwr^AU!V=P4!hCuhB9R6K2-L2Fq+}M>eJOM%qn_qx0 zsfbF}1FCc9v4$A|Mwaz1USexN9^e<3P!|86GoFK#DcEV_dg1XTGeB>bRHiZ9+s+G* zah|Hl5IV;n#p?wk!~;;iueYafm<*DW08!+F^(53+ilKnhk`|u`k_Xb1DtS0vc$^Gu z&By0RQLTdwYoq6No`#I}+9;fjR3*Ukm&Q<9y9l1m4QXZ!=UzAa1|t+mbHUeH4D|33KcFSQ`U zxp)7n>E`!^8D_#Dklj1utAoUalgo`u6HlG~pl)ExqH9ZQ=WF{@Xz~iwLyZLb1?uL$_lD|0yRKQS$OBIA z$m`cR@xAFv!^^0xr(Oepk5u+_l0Pnv5?NqWsS@ETFePX^_n(T*@;NkyltEtrr@laL zAX7$xwas3v;j&HTO9HN`zE?gqD;2BttFlS}d~gyKa5iM~XBqI>iB6Bd95NAbi(v$L z-?O2~7I&CBfd7zP#7`*P*Q>>cmnSYQw70#5afDPrO3!&wq%7~mId}sc{bC^4fYx~~ z(mz~bt0HGtzzpUcFkJTkSVHbK_0-BJI-pV+&H^V+2fS*tf&q%-zKJRf(tFXMhZ7Wt z5W51DJ*52oo}cBq&;t~m0nsYNnZcU6_dN8x0v~cc)~l2E9A6_9*kE%G<2(_w{OBz_ zuN7+{M0wPQw<=f{}3k z)93&+GR(jtPJp-{mLPcAQw@kM-PtbU)&w83!FuoGhkZ=e#RA&!FJ`J_MpQVY`>O8} z;^b#gP@lu{mQBP5P?oWQM4ThScUiWnGg}`rb+$za7iaDFTs)JEK|$6C=qSH1AFaxR z0zpk3F;`b1g879lJtv&~kAdK-3eI+h=Pk7*awE0!4FE`zww`H)GBEo{{#ibo(QKdS zHag;x30UOoA@o6)?js01{GD_Ho@s7D9;dMEfaP5+V0yJ`f%6MN*=ps&E; zNNe*CCS_-J8;2pt0W5pAXy)m*pVIwXTM;8A9S|P}W}4WlyP;WAX2XN+?TC}?l`u=y zh)FJVHQX&U#fZ2IHKOwZrgeD}`t)oZJ|l~BP-5W^b9O&Hz4854+24Ms(^BQ705V(w zH~gs$tFaYSQA??J?X=5XT0|^@K>&;|@gYbOfi)5zv=f@ccq3zq6rt&h@-^QAie~f~ z2GC@IesSID6%!wCsu>LSI^)*0eD`F?Qm3j21yYr5RHd7auVB&q0YGtKNg_-Sdz$m> z8+jP{6w-eG`!Z~Dz``4z?Zehx$uFKKW9}lTtB*`oCCV!-Vosv3nG&ji_0`Mf-^~;9 zeaw&E&`pxIMFVFfw0d-PpHI$+0;lt^%-SGk(0I?@m#mB6SCy7dB$Gj#<7$!0wso3f4Xt@bW-rjw*r z2Xwe(#`9}N9t#8@p28k3xA(%I_14$Kve)Z3TfGihzcUOlBg|U6{Y77xAjH_^0>pgo z-bRF2d*acis?k3{q*PDyUvmGs){i;9!e@ZwtUZZegc-iqVD#B~KY71rn9{*(sbR8# zXmYD-Id*;=cUYJp?hr=^9$`AcrJv|UcstF=X;m!j7HfeHH`)I*^I}aiJ}5(&R;Yw% z#!*x)EYI8FIC%zm+Os%}s;yYI16n?kD*%Y<^U#(X)Tr|7f((7zg&}9&s5dQX(lxtn51tQF@67}T|t#0KA{GIy|YJX19;9dbRr#Q zgr68PoiL3hPp~`LH{~$g{*vN%5rsWc%Iw5m6zm4o^>9EHLeeG_T9!^;w0ya3;$mVn zq>N~?1-bo|y#ej=l@KIe7auAx5(Gw5HPy0FlTp|6!bsRm*2-Cw|9qIPx%xL+2DTI? zO4vjFpfD6l)*Li1{nTHe%lQeI)B{g&WPb}@yw8!kSg2$UQ3^%1*M6VQIkj+ z5*^7;n8$iJ%z3)w${onY)R3mNx}$|@fWLn@kU0saJcA2s%7ow!-}hokB9baorB)?^ z{9ZUdwZmr|VHoLMP)63l!8B@tjxtz3`jg*TSr^WH+;qF4ZF!G)3~;?To~!SHGAd;w z7fA=nkHR*1%!j;V2#dzM!-W2s>v#*OX+HS*)S@?3j5vHA^TNxEs)uso%LyZlyppFw zRS{ila6$7hQ9+r_5_0d7$_C9>f4jUtJ!-WsDL4y@2(Y+6^jA2{siiui%Xf_dck*?1 z?;BM6_MgYOsCV&L0D2^h?n(H^X_P5XLXnO{? zx;76dR-3neP3%oJ^0vPXgpHm3`zL+t2Rdua9kKD~^Pu+~;a)iZ7PGE*JHlv(Ek0&! z)!u$P@(~^y@D5KJwE?Pt#gEszM#PoJ2~X2|dMS6T(?gjX5Act8ZAHTKLtRvjlL{UP zv{w(jG~X2NCAjz%xGnJ)bVOZM6mT%FV%DVaK>&_O$Bc3<6$clVWSq#PQ4ci6rm250QSul}4lqT-5 zsCSrZg@Th55zykG8dTh|lEzV#(_-Pb zNUq_^l=Fe|R8@_P<&KrAiqlWO4f6(E#1ab=X;(t&^JIcL_A5SrB5yX^mj4f1?-(6O7-xBR+_7!jPRF*L?%1}Iif!Ar z*+Iv)*|BYJ&(6%g@9vqeRrNe|PJO64|GM}7t~2D%f|`)cRbaox>u3XiFs2wP{h3SP zD~L-;u>tXWp1M!N=jF@PV~Xct-PP=jt>CZPo<$$c?`XooRLN@K!xCbF-;mtd@_#=B zlu)v!3fo@e^IWppqwK33S>jZ#_i7gtF*vv4k_w5O7|v3Tvjvnf`Ogq4c1z_pyB?~! zjm2N?d$9=9@xBQUU*8x#af9U38v>>~MosJU<(>mXo-H7?p_hU!@ zQeBS7$`A5k+5UEVZCmcnJD{ef7L>*YX94TsTr3#!&s>m14kX)ePnA;fjwuYiZ4eb( z2oL@-3lZ2PfO|yv#*g=05Dr5#TXafmSzCU_Z^FptKhI_G8DYVxDS~-`ez<$6fSSuV zEgox7CnsIuXOISYlBrqcB6pNYwB0*$ ziGEzToVVxJ5t7z+A7`bju%R`@X`` zX+o~-rv(3-#_96f!J)v z3_MRx3T`%HQ0B!E4zYpnahtYKt(+1J3e)n_1~?hhl}&!0Yxo#cG4dFcbtAUunsC3% zz9BiCW6h{DLzwq(*G5Fu`4-Qsq|tVGwo3p+c_z?pDdNfjRnMews&X#%ia#?ap|5T$ zrr+x@y2%j7@4&D?uo0A#q2tlC7Zm20u=w}#&Abz9vl!C`Hm}+O{H$)KTY0yg-U_#v z1fl22ZrcKq-c>Qy==ejhuK6`lPl#5px=dqJ&BA!u>9Hg2wB(I_9$GO8vdyOW=m1GL zTP4y&n1?zfn`u%dX9PXYDmyOL2^w*8K2AV9kOlg_zP|1dzH0%#@~S0&^aVaVb#s0$U}1B8UcBz~bI zhZBAGw-5b6>?V9EKbKv3b$RMp`O2Rt&y)QlJ26ObKaR?u2*z>5Jvt_0FK?zWz9bnxtM6uif+_xHj@9ik1Va~W5?U=OGRAjh9ifPFKh0G1%n-RxBsd2H?0pbvED*#LkUE>cjUeJ1#i|Ov*8gOlbdRl*^z)p*G4*JSrv|Vq~0F_=Twv zr=C_Yn>O3X>@ zhZuALdO@h@Qv^qtdIU!VM&w~6N4R=8N2GdWOPDU24SF^DU}Q=pMnp^GQuwYY@I}#~ zz4C+)OwXM&8k>VC*SVl!20@C8Zca` zlwvn{qk}>+ynrOy8JLgm%j^jPY)Y0?Nms9pQ)#mMMa^j4KQ84#uaz+z8}RtodFE{u zA2u~5F}8@XwpBB9E*~ELl@mo8!TXcy8Qdu-wr^`RR-vj`;tU2{$3Y_~Puizg48gYj zxl$H#;ayq7_S{@iEhL;cK>7s&SuHR2z2Rn&Y%PZW9F0E<=cW2N67ye|@P6;##Xo}P zN`miOXEjPvWxQ;WY+n9QxJnuaWvXh&G>b_}wX1eMWk*lOP)PXI5E6*0=m&A-vLUs)593&H7YnpAw&A)4(y5Wxj#Nm017mLYV$d)4 zPJNf~^1tq^Xq3S=dEmft>$*xd8T)qH&4Yy0kDlZvhY|rjNk)6URarqp6Mc|J9&wiR za8WG>HthPq$GAZah{8Grdtu~i-=b%{W!7%0XUmmx;;{2rN>vd-LLgbe#zYg`e|5jH z^Kjjs=4<5RBB*-7hK<;f%NP?1*~{Xgh3@Bvj!@3X581MTVZy8HedMiPH!IOfomDstw+<6Xp6IpKwbXHHiTS~)@Z#xcytx-VxI9LT@oq` zX4*PKNcs$%S)X7_d;V56D1280YsMIqa&5IRqKw4$?`KSB6*C>LdH)in#89ViAy80L zryJIgk18iXoatEapoU2LQs0W^+8@a1I7GEE%V?gBs79w$IgY(d3E^ca3C62;bfoAQ z=&_`EVO3G$y1cmP$l+-TK2)A@Hk^EnmOty0a3iXm!XWeSK_k;td|# zXyxLhBi=!zS4;Jp7M8~;0#xVO&6#m$5QCe)2g!LrF{h)n09!zGW7^N-ni+jG%$pk^ z!W|-13hx56a@-JhFlIA~5!Pv#u|hdIgBfo~nItc~67)(q4Rl9RnK`8xyq$lP82 z6x{D(gh0zNfJ#i$VhTc0fd8yA;}aUJyTeh-8M;oG0TmbR1WH^Qxey z;%gj0e-3DCcy%#=B=^Q4&U`oE(?b*|{AK1`r^weX*GGB1Zx!Zre_bMi6g?7F2@mZ> z=wqFaBn6upRB4RP|1Tr8i-mBm4}<9f;v$|8kF2*Okc##;^3iwCbjvv9uIaHwAb9Eb z@f%AFknDD>=xXQuzG2nh)us0n77v2ezugR2U=eT58Qav-R)QPMD=WVr#Toxt6{K7L z&@bOAa^iB2OfEgs;~8Ad2RUty&hVGUY!VcoLv?6~xbV{CV7~}fOUGqS?)%wv_j_EL z{n5F}b(hq>BJ<9>*aiJU@cjm@qj}M=&U`^UJ0-uEu_oR`1bd{qxP?xkxE<}P0(1d@ zgN%KiCq5|pt3T!1Lk?|{k8xXxZbyeeJei*)) z70vaNvxh8@oU}NWCB;F-1I97bM-Zjnrsque%vFinn*>j8EZXrW+bxZF#DT{Ojkj30 z0v#N^g22+yS4cni{77(OPrjU zPzm)L)JxqwX;mefv>&s2LzI30a|l&FlWJ|b5jSAN=#-=dB_0WLvqvbgIwmI$)%Hy`rNiE78i70sd>8{_ zaKkKt+147~f@N(1Zk#50A)*+tyt>qbM)@gKuSkLhliZi6c`{%=OKFGrn@v{lt@jB# z?RzOql%@^4xO6t9kMBW9a^_Ns9hl(_ALUFxDg5z`K)%I&x=b$N7h0G=t}YD{HC&3Q zcJRXln0GdWPBPYDSWvZ4lRYS3eswCjh%j0CD2wG2XnrsF^55!~mQZM53u1Ezizy$Q zrfdy?Bh(9t&%mmL&%-925zPNP8|C-9OZ@teX5ySE!5%B z<=&m;Tv61VqI^#cnN4-IjSD;9AJ-BYCH|kDFzt+nbkdTG!O0pU)(x@okj+G~9 zC|f!CA(gin74= zfIcf(yir7CzvwRtpeOFl^|Owp`MiDs&hstj0VfJ?C+9odwE_mMgHNH*!XiC^jHnu! z9rG&F1v4eO=Df4`sTeVbPx3Wgw}J1#wA!oO0?Na1SZrRCBrJ>#gUv!CTu9tjmD7q` z3JxoKKt-wc0|vdW>>tJA>9Jx&ka{XZv=cnOtQV%o051|nz*u4{aZsNPZ6?pCnJef- zPCGQRap^9Jkk8C=Q3P2u_72%(8(UTncLZL4VZ8n%ruBW{>{{SN(MFWiKC7C8u9MOz zF$w;7qLd)(eoF5xlRK8vt*~>#<*}wCa!I|h^g>dl*Vf98JLn@%{EtvgcM%p$I7})W zX-|DCWhv1=R&FY5kJTi%#hT7V58Md?A&O-JiI2%%z;JE@6K&#xlhZhmn`5+twZsnw!alU#O z0Ui$2Vd^bOHx^VkQ7t>Ue6#nI)H=)*l5l^hGdlbXg$D z`C5yZ#%F8GtVXrvtPHgRReD7hO*$9JRFyv1fZ9cHdjrHq)F`;KiK*3jdMG|Ac6RUM z_%L4=&}!_HLvK3JdgNg_r{=&SS<9UIX~SP5R}F1;Yf|qcpot9=V#JN}JT+M~&ORi3 zZYqtjFW|yzu=T7H0<9@7^WiCBQ@w7Lf4ZFmcQKn-p540E$yGUu%)7dYQwG0e#E<7_ zVqz_YIxu)<9<3UCacF1qG*-<$ZTD&6TFb`<1lb0t4B%1+jxSwq^!(tfn$mJZ|65QP zNHxXC@2(#37<@@C5PSWDl1xNi0B1JxQ1e|sn@gV}cT!cQysuCNGx!gk%E})Fz34F1 zSGWUrBOQdIuG^z{dt@A@GA;4)(u6}>`YF%?)q|4^=U?w5q7T8N{F|TU&j+(2g(wT0 z07vq@#-cPV3=FLC)@{j9%n-uq>J4^LCq7ui;$^G5!veg5M&#V*ma|#~J$sqC+zx?% znWQqhx|s-dedUiks>?Cn;n-jCwUfH3&%ZRPwuV@DuG>U;s@@&IMVA#4YJB*DLqByB z%GSudh&>z?K%S7j5HF5h9(g?F*r&h_0UVjayKk53?yd`%4O%$TE#9?Ar7L4N$~n3S z100Kr+oLT{+6*(7F@zis8l*;dlu)k--*(DOoFbAvI;45{TG$9&kzg6ox*TiVsQ$tR zMqg{!aYlbG@j-JAzNjpJnzVUX;@Q%gIKbt*TRCyw2|-jr(qmyID;dBc20?>S1C%`4 zR&SuHcLvLqUxiR6p~^dTvK*SCB)Xw=m-HrAgUU(1BX_@i_E z)oMkSsfjW3KZyQ;?LtFE0bX9rH?vKAv6k4QbLWhgoSc%8ppLEH^_F<;9~B>HNI*LG za3?qVJ*(C-#?eyFU8M)h469fP7C@iHMKmKgv3z`bE$aZgQ~}VxjG;A?9rNec2ejxO zcARog8mNHlb&GsSM;0xVuQy}tzZW(AO;&MkJP6OaoXg8mD{Fqk_52e#yJHC`khlqN zdSltRyFG*k)%ltU?AU!vgNq)&T+u==qh8;Id)oVr5fvI-g3{|Pq$9AXfD#rWc3wD3 z^lijIkV27I32ToU)l$M-dN_%$*qR`T-d3UxY}{6n{&9T3001uW?rN1U(o@&Fp1*1_;64!1%<3^_P)imgBMn|ircLnO-EgmOholfI9eq$4?qCl|@5V1MyQa9{E^M%?lAz zwpCkLaPix+>EK$&uU|WIa`7B`i88b(4<=)L70&9VQyfX(Z5x@MFLn*{K2?33QZf+CalVm(D!(Qor*NCp!DSW`sWTxuy!k zVl0{4`3pa{u{z~DP`$6HbC!uJ*3M9}}^T_B)^HKjUU9m0mn>Y^c zztOn<>kB(H)s<`0b$x&7b;oaIRLsBQ=wy*h8KI4E3L>trx3j&APt^F&Ve6HOckR@A<7{Q zL>kJfICF&nem_9Dc2*TSdXHP_gqZ$}v*q`o*jt?fPjVJ9dAdKEHViby$v!StmBLm( zM|Msdo+mjzm`0ygM@ZEYbq-i-ku$K`e5dDN5%uy;X#29*Q-sN)J#v6FwaIk_g?#1ICOm>WQfbvfayi<=Gi!-r%H;ytM3cE=PTMfC!r=|U~pMFnW%U`g>#utGGUTfWdLxa`L zN{6l;Ft2*6|86i|JDykwQEb(NBPPT4A}ONWRL_L?iQ38{KBKO(#|W#tp~FX2AY`!I zc~9(3JXUy6KZVQ?+J7*oji&C&>(^E;pocsvnL23uXVS%rPI~-#d<0j`rvC@HaJf3| zB1X0bAQK7-${Ew6rrm|GfQp{sUgyy#&hs!LAuKO)JYmB8>eIMS)Ufk%E>3p%(|yCc zmwbR;tCVp$WtM#02?F%UyjaZYX$1`Gr|OZjrfv%vH9@*YP1L`Q3Kj#MpLASn1v4Z%Kye#99Fj9d0w$`y!&ffsv6CVYeDMXDDChrUy|W<(KFzu0)@7sN=vutU0E>C(@20@ZfZDPG_>~s#9BO z$-xl)l%w2XX<{#+F2p=Xu;%48;LuikkqP!dq~mFQ7lPj{j|vNuKbF{t}O$s*ob@p)9*aeepe4F1tT zjg~3IL(ieYx$w8~?sz`~W#%t;c(5Za;7{^l+|3HLAc$t?pViktvu^{XK#3o>c1HxI zJce;#lR`mR6A88(Kj3u5nQn#G)l|qBW~zl7o9FI459Ka^ADCPji5_q~i0^DHrGLKa zH*@OfK@w!V9R24c)vlmq`#K01YBD{G!X}voz^2V%$N%pirYQdzG~)U%dN4aH3rDKp zKL-({mXx%xhG?og8RQWO8^?dNBme*5ghs~t28Q~^#{1Ft_l_`bv#tK*kPx5@a3%YQ z|M&j?x&42aE3>n5|HtY7ILQ33W_eZ}k`huUB%dPN0E4Jt=fnO}5aDF71j94biU9ft(9|FAicu z1Km$bY_ZVuuy~btMa6$AB9&B`JG|fj&1&|U#%<<%=kwIL-IeN3|0{qQD@v`lTlx0% zG4;#K%l1+sSD{BU(=#gG(_88kx+J}UuY18qC!6{C8L)K6x*-s*<@Mv>4`arTI?v); z*J)GM{qW}zT6(=uFynhGB;?C&u1=qHSGSQNOPu(2*(OZkj!6B95 z*5haJ1^lDH-_}vqcWLrJqFPg?M5F5muT*LxKeAR~dBKklO4l#f%dLQ|kUBf9I9kU! z=#S3JOfjKP(8>@SNen$V?3xfVy8S)7PDjsr)9tp~{p?7#seG(DeU6Inqy-+#Cc3O> z_0iCyOIm`l%3!LE7cVTWCppU|9KSKwoU?Hm0#ZK)!VS{c;6N{r1H$xdnd5NAL1+j5 z9Gy5g^K3MxqJ%oIbywwj{>htbJ`gD>01JZ5922k~MF2BKdYusZp3z@I^w&3aeY@DN zC7Z&nC;r{{)NZJ5l-yqy`gq|KAxoLg)*xTo*(RkUrT(>%eEmtUhz4aemI9TU5F}ZYK**x3nV1b;K^E<_a zHOvXF>vJAdZY9oov#r2Gn=HXMo!;H+wXkET`8`y>r?zBof9~mZ@ zJj?94VFOU{&V;~Q5)%^>>elj(e5|HAL_l;jQ9ca}mVd&b!X19MA)$RuCN~eNrXV!r zd&jE^F7sk`pUQLR(o>rG19ys0&7MCpCZyWtA6uX_(B8Qt6yHFi_9=|@G>VHfhX1N) zk&h`oEsf6s`x-(foUAs$uthCl3?mT7*!@Pf|3+Yvs9>BC$|zK;lnp5WleVG)1i-`w z-Qf=va8J93m-B@wz0uL}jNn91QRPHki+qWvDf=dr_>-vWg6bQeFXlI$4Ke4gRWE0} z>ol2>%-_1M}$^(0^^D?WrbL*8!`kTC}wci zZn%m~vc<%o;s!Y&(#`uD1fIIad=2(k7YfPLBsPuN)9JG@>{mKRBB^rxPg6b&*xZg@ zT?F#f>Cv-q5jxt{HF@!%{ArGP@pj4{y* zZ$-h*Vvjsu(PNZvpSv|j8H)sk<7Uks7sktf=9g@b1JfAvd5i6Z(6rl?PeQ6Qo!WWB zxfpX*5G;T0Ky?mVy8H-x&d={gz7|U5p2D?6XhsD4OocUH3{$X}rIz(9_D@PWynFKd z_K(rlI8g{fz3K4dc!I4$rW^Rmzhz+j3&sWnrc3APVi?+bzFAoEC5y!`pl*L2$b|Xl zh$`f>A5#b5l+snr&Fwr=VbX>5xZhtCrVhh-k_h21Huh=cQ`V{KK6g|ud@S{ z7V*GpSXFx3y8KP**WTI0@I&N--4llfNZAe%Si`PkzC9lbR?cQPQvmErf>NTRuPeGE zMcqPt!qvq&uTwAQnUqH%LzE+1zaiA%#EEgB5yXZ*?(~PR9H)C1Q6jn$-lcnWn&aJT zo97QHTOaD0=!NSQ3zk$l)xYU_5xJg3gESS{1@JmvxNCr3yLq9N7<=TRv}n&$^d? z84zJN`zBF2Yjpp>rhU^_f4;FhhQUCc$#~Bx0)MTu-nRSN!aK7m^BKJLPjS+-NXT^A zH{rJ08LMaTEZ8H>(x?d9w%n4seLP>)0ewa|L66-$ZCIHPMg?T<)Sy)}1*hkne*24; zq)YmdRe}Gu<6C{xrDK8$d@e6A=4eiM-Cj#_eWo?RYI7rD6$4t2@a zwpcOtD$bk_!w%q$g1m1bPff=>ic2=etBVCz6^>X>vF};An>ss?m|By{EX(Qr2&L- zM?bUOI?t9B`R*B<=9!)|#?xHdX3bXY(ev&seeU)Z;%ajB!oAWTq?i2!=Q3qjk92#)gK zw;hL5{K$=QOAU4D3j2r=zH3}m!`7^>13eytp){HFE^-&_Ml>sr1_QsT_5{6&`yx|6 z_Z8rDqNy!tCtZ3Y^{LsK`hF7bwYQ~d_H}%9&YwAa2!_b7<5Ontvzq#o+tta`8SeU0 z9$q8Q>gb@v;MC6Jq{jC1hR^g=>|P{Ax5_kgBBA8;SG%9tyzZCjuJUeb(U1M}0NZ!b z7s=7qCl!UJkGq9WTvpV*T(2(iB9ypJDo}u{x45g@y2`;%poaVVk-jk*H{NKw{_UUd z1HxUSBkuYj)@?m|u(Ruwqn)IlKJ^4oWwhcQyE#%4MOU0wSxQ%MT?r@p%9RIfmUGN` zys_#gY+_ep+NtqJr|CMf_jk4QlM8EuPOtyMd@Soe4U!v#5nRxfJ~$V3Pz)AF5Oo0V zeI94IdEbdp_?4!4RwsKHhvsFBAmc1*1k7a&pPv)^tUID+HuIceKbH# z(P&Q1p3|_Y!hFmjXNMZPwhLd=w${|MzA?=xAuYqoujbmIvMO8iiiF~JrQ8cea@*Q8 zBTWX@**~?XVsB!MTV9?X_DVLY>B&Ie*hIQr#u=eAVGQz4eQ)O1HCm#)CDDFy0^S;T z+nTumy)=iN=VORlTgAY_Iu#{7qdn{gBR$iSf>y|UjY~h zJuUZ5e~;rw{mZFl^}MB}DS4aT={%`!xanZPsK=((e|>jvrt+m)`sxHXOvndlLkp#N zv=D^a_VmzBo#ho=EL^~JBqb@wAy1~uin$lSCM_&q=v{jPqjdQ=ebBCre|Bh8QK>D@ zi?Ir1dtEaa*!83#_?4fZS&S{sXFL*u{bkb>5$TtRoz#PPZ>o;^`hxeHfmdk;V-cXN zL(B;-cps9UtaWov?WLfiv#0^OIZ=1@IMF^M7kn?^##zUHz*tD8_}1FW;&p!+Ta_1|kiu{BQ>JD&FAt1d zw2Dw(iW&$QJVF#4Fnny4dTv5NGIXL1J6TD#D<#e8&PK@by;k_qM1u=h%xdYJ%c&aH z8_PLJBe*6)(WQgg`Ty_<*gTGRa>eo!VG}Iw!nRKyBP!gpd7?XZ=eX_LEmf}A!{=R%Ryl zRAL=)oYcSSkXVpXV(KEoN~zB5kj*Hp9RJV6!J6t{28oqALj{RP%*Od&^N5qPqsc!k zgL~Hh8GG)W;hkJzTH`n%vp}$C+8SH_hpC5?IaQ1ck{41`OF>afqcxNZvi2Xcfs-Yb zn+K8xI7jaUCBZ-G;xss(m=J&in_Hg=0l`Cp4bbneVV=d6vz{$m9!M)=R%%3C-9NZs z)x5owyX>^9Zsj=67~DEK|M=Mc`q=J~5Pe|H7bTg^8`N25 zaXZln?Z)&x--=_iS5d7-oEO;(l6gDx!2C2Vi*3R|K(F99d|$-(ad=&1-JMz8^&mF} z7-*R2hkX zsmNGNhLD!hV-o!X$bn#W35GJE5^5Phzkp+j%pU0(8Id2NBD9d11i_vLlP|6)Qr1eX zG8Tm+4PW?P)}utXIzSS@Dwb&DO%H>z$*M(HGT8jFb%Hs6b@nO$(US@;eL1s!+!#fU zI=$6)C5xlTUbo%L2uY7~znA$LI1G56Ng$dFE=k2uNA-AnBNSD*dgBG zxt`croWo%BpmTe#U0WT>OxS4-Xg5Wt3G^9=9)JJ5Xx(lByoN{eNq>p!dJZ3Et8Dz3 z1L=w6t*U_hvQBM2P9Z=f&O|`=r>MYDUIoa zx9{#@U>@40Br(TbMmZ=r7aX`)fM@9|m1?iNc~GF^kYHy;U(?JtkGN{;Q&H2yGI>Y5 z*!dA6STqcwN2I=&`PRi%d$^cH6Uxy9_caXVTazEy8$+1&=HI(#3BiEXpwXnnk`=jW zz!vEbK64Mors0`<69$&*K7F?%L|dZ7nh+B=_+}oJl%M2?Vu{%pokIz?siK7^wXsNy zm`!3u2I~xiBWGBE`3ek3UjV6M0o9Z6{B`XiLt#J)9S8+){`Vq}RrcVS-s3`a0Rc5(FYeA+A8VCf_gtxB$Sm?Nf#5x<8{4_v zb)=h05##2V*i|GFo3*x~o&gfL=a@5E{npS+p&a$Aw{NQ0a4KZ5+7$3G&s`?R#{=isPzCA;y`~+jEKl=83tQk z85Q*YN%|NXcPatCAs5F3T`Lhu^Ld{B6jc!-G!JX)yV+(&_7XTmUPwRz3mdXW2B}q6 zTCOY=O{-tg3b+Ef#|J*C1%f|8M|6=ESojO`0~~kXi$pc!^Y#ScKQxmE-`)yawK6^^ zT+3r^$~`l0G(uqY6>8p(h3q`iLR6lh)E>lNJk+(NYBWI6$zZz__b9o(5?ls}9P-*M zDTfC2+f$BDI)1{LF{atbNXVJ70~()#(hAK1?eWriU**qc5P%LEBAAyC!S3o~Agk_h z^x8N<((Jx0-TI2-^)CXrmDD{#yKfwo)Y;A>J-C5eqxe-UQ3EGyen^!SxXce0f)Dum zX+mOFgz;+%SJt+(0`0!1QN#qK%aD1wHy3)FHF+-3w|*<{vrVvZp~8X%zk^B;GrCgC?2R53-6ut<{sz}bGxA!< zNtd`KnJzFD_8=mgN^1S#k`oEcHENXCPG z3~wSu)S6=yR^?DzJBBNx|I;0p^%%?j@blD;_i4xnSh|Y8QcgYCdWxPLy6JRuzhN9G zDiR<3FvoZ1V;(C)4T|3ZXXu;F>0M&7sD)qkAH8Czo(;*V7mdul^_bixc+26o#zq6k zifNOj%Cq`GbNT*7gTG;{VC(E*@9SZ*VNMIyjNqgb!Lqe|yG2bnNT-&zz{v@c!;A(s zrP#6uXV156dcS`{L~6vFUY1g`sJKVbA0w_+UK{>qZ6-)~{1Pu0aLKWWTFAm1c#$}} z>Rj5t)07?5*&jDb+Q-@W1Ps{O>f{23S44a=dp7}iK+ULq>Z9jJ`N-OJv-RYbNcE9l zyQeRO6uIYY6?gYkaVTg}gQKDl`JFVt=VG1`f8~KW@UDtBu6`su$v1rDj>gf9BeD=D zwxCJU*^ls{oJh(jDXm^)MpeYG&bsgL7j#NZ2r2*}ZiIt{20t^F&ThE{)Dr-6yrxns z>UAFEfpNX*K|$_bGMc)i3c#CTLZ?O=eh7)miMlOcv?0-FOv^WFeYw--g3$29R>~ zy01fY6I8ayu}b^tgXkjr_4Xv9ZGHD;$0fP>ocTIlGS%thVznkQ?qOb?Hkyr-fqLXv zlD^pmG*mGQgfUQvjJ(pGa5^u1dncN^Bx0yub}P^HTqak^%#RFHL?Lm3b92V=Y2`zE zhw}8BxPc(Gq0>`Z8ke_C-19?)b?ea`-^LHS-El^@dI=vm%N;bS^E+cq=6hkW9R~lc z+#^)H*(q^naX*w_9yAnwxn{G{&^Q5*y1=9P0w1sV8m+HdKh0;TdKLvKu5C|^h@)yB zi49?$0{IAJ-N+z%9drxe@zH_`xzHBLCAPmwcBy5{7HP0T<4K?^ugTgyO<&LudcT*D zhgd8piA(ju#B7dd7Mwut1A!jrZU0E!TYM&Aq(c-ZyKP&)LX4 z7E7bKF!zjQK zy@bE^9ctnS17!n(JwaeICcW3z_T%WYabl z#WKb2iC5L?mdsZ~Lp($-vP+Nk!qYcTlB6a{r9-#-!h&9Gz-Km-8Ww9>PI#5Ez>HXk zP^j33n?SxmLRj@jU(&)#y$i{)_{pZ>z+GchLk@Ll5V(B4tXy(n0#~alM1MEin36I;iKg%%`4qAiKhEM6>l99=VDm);{5l(6q zV=(fC)O1Vc01qz@I*(A}IwP=#{_e(Gr=5|~RZj#9dY4t9&p5BS`N(%#`tJieSw45W z@6nsoRRbvw#qjJ8u+(dynm}|a`SBA1PkhoWTRK3Ac>hr&6yjH zyjDX-Jiq?djeOe* z4bcy)C)<*^=>NShzgj(atBp#&yk#yTrg@i_E#LU76Zi87DrQ2tGZ-}-MLLGW0NT%iCwYJz9?}n*xpf?e&JyjdR1RR{eD>8o@(~&pB1^c`Skf zC^B1FpURDI{z3}O_>%i>3YTOIouYg9qHW83CzE9HqKkxLZA1 z|HVjOjS-+bD+GtCVr+EUmdI)p%(4%VxgPd;$x$smq1~Lmid2I6O53bvXq#HZA#(~B z`z0I#dWdqQA)}{J>JAO}m{6+eg#4L+8}tXD{P#wS(-50kx((Qz>xRiz9z>*EGNFHs zsOH=Hx$)W{^hA_hhzbrP-XIoF2yqivFft)c4j(XthbY*LJs1bOis8~JS!)2~ZH7HW z`E2Irg2;)N6E^h4PTsW~p{Qtrdi-D$W0du`4{;@h?o`6}dh08dSYvacnQIguK^^tN zCssPhkjqgnpO6ZG3yTR?81FS=GMWmV11gZb7B&^-m5;ukdn7;o%Z6@R&b*`yYA1=O z4kisI4X6hHai!o_XJC~UgVF*TGU-?x*YI~8y?KKFrPRGqss#dMpQ(0J!auTwJd3E` z6|5zYy@e4@i4ch={b*PGpt#LhKLqJXwRZ#+wtf#zO=_*9jh?7Q@BfjNDdQkpW1O}5 zbKrt_DZm{q+s5C0zq84TuxThYYAHbe_d?;?HSpW_3z69SQ-h-I_)%5>?F7}nNBPUo*|ZE>Oz>IF0biOIuhhsKbm=>vTwNNx!3;0fAUcjU@wKHAkD z!LK&tk4u5PuY%cy!fQ{U-v^(0n^WmJdAtZ`N;q^?0u@0ny_rZ~Oi?XMUa!2mc2k$2 zct`uJ!+#-iZ@6_b1#<4}VEjNPpww%y778#OO00`a{qcBFeaNQEQ|qb^V|(OH%ZJex z{cm>%M%0H0lgH2T=9aH&< z*dxs2T<`XRa_#1rrl?CRl2$P&Pxn?ofHq9r3Xq8M*;FsmiJP7`4|vP=%B#vfT8!2(_1h))$#}W=SDI7TCzUGluV*<`q!Ds z_Cw&&6ebT~{i%+fRH zR_G3*Fg3`~;%NV<;)|r3xi#v(HYF>*u4=6k%N*~DY z-Y!NUMmW8IiCCcA5T7}7tO`wW_ogdyadJSKcwEYJy7Q1&6o`TrAwy`w@$Nk@V3uUVTAMn^*Ze{fmmV z!xFHS#F2lj_ab3o(7~gU?>C`((sD7?Fd5VvQ|vEBjRUbtkO)5NpzQ5OajV@TlHDlM zkDh$V@BNP{*5%}D-LBBWY7J(0aEP?LLNqP-Lle64Q7lJ;)(JW&s=K40oV|^Uf`Mqz z=CqkQOx$#ukVIv``<|7cZjk!V^jYxr4F-^HPRFbrdvBhu8%6gVN*DFy;OasNABl%1 zYv~(Ovj6D9_E&X4i1MrKIxnxHF6H&TZ{sI|NB2XnybmPqZdf-csP~ z2!>ciDWo-CopttfBY0nnWX}W^GARrA?x!}4O83!{V++FJ`ND>i#r9b7t*@jJ=nPZ0 z6nlUlqg2Rb+&$qpUuAF;^c+zAOaL<8RX9Iu2O)on-<`DZrgx%ge0F;L4!fkaT&aPf zC)#<*88Ee>mPztynKW$Anqln^bGxawGM}kWBh~pR>aH`?{1V^NqD@chL zK5KK2>-GDykGO5f+isE1Vj(IRwJY-DG@$+V7;kXZX2n_MSa@YbAC;^{j09lYzo|Yt zdS62sYky`bwiM?Kq!iE(94E!e3+8rnxH?+quh(hV8g%%@WY(B5sYEoIaJ%2IKnhZq zlFn&%c5cC8X6x(mzA%^_Q210=AzV3y8aqcKo^6iqMbKJR^wtu_);H+Tl~yZ(qrR;} zDBQE*Ip3e@=}Wfy30CwXGy%kl{-R4U8uIaJ>gu3QvYJ-H&GWN}qKgfKm4DQB-Pq&z zgz5?wCjnHWPH2s;{ge`K>?ioM!d`*yo;`c|PzgGtY~nVW3ibx{jxe6wfR!&^=HGyBWWr3z`Shd;8 zP0)vlt`7LJ$u?00U2L<2y2rRunb{$()!(IRBWKO{Os%_w(Z@X8*TiIzx@#&az4^7K z?=fb!99O}omh~DGe4uzn+F;+lPy3ue-xe%kl8Evy$4(Obpo)*#r+_AiYcfxX_#CLgn%ur}A<-b>IB z2kl0KYMuM&-OGzW=+6kL;)jcD;s;HORs}&v4~i2~$0R^oXwhFbFPqX0}RZ zk)Sds_e&2=DS)Y_A+V)I9#@=-GaTGPm+t)XQEY7SgSYW=xn_3AUq1siwii;JyJdA- z-i{J^l=c)x_R6si3OdgpM9w6P8V9#rGY_p|U!~m^7qMK$m%xKU2E62-E!b})Ft#_p zZk8fwuhe8}&lG<7;Z8)CQ*Je9HEs=cG6*dfRoj}wQvu=14mQIz6|{b{zoc**$yWH7 zg>cZY$~6UUO2JMf%}?!$NDXryAy*d1Nm3#T=6rvoHtur+V_ey%nZt zk?9X~h&^hxq8i_8wMu&CWNEhQOv4u*zjy;JtpZbpdL9`9ROW3;qF!6C|2%tVbE-$| zb6lG(Au8y-ng)*o8VlE7oRb$_lt%GkzV9|??L$LNZQ2c^&QBu+0}al7w4O}NWE^Um z8WF-UWGh{99B^$cakw*Aq!)Rd_ZdQgHA(QEi3Ojyhv!892rP7qV7Q1J?5v#sZ98LS z=KN1nw)$pxhiBDC^JWDTm?98YE&5{{Qs7RDA+hz{~uQzNH~b=C&)K&&~G3h zAn^aWx|LcD(i4P~=Pc*(f6|ElV~hXokz-;@{bBy!5|xs=ingp!>Zdy7ASf$q>P6wd z8^7m6Q2&#U*izv%A&G#Mf~T4m6KxMs>={K`tkhx2u#nUiCFhmNgiX1}cptLW$&$FD zaD!=Eq!EfZYXakWx^+5Vs|lY_Xon5QtU)}xtRGh=tyFH->A3xgW!!#HIPUp#hC zqSr3RKYYF|!Qqy)DqLero~D_bd-kDnqR!j@YU{e=qbk<+-7E|}C_U5&NcF<$1rSMq zBp@|F5&|JNB7{%^Mu<`mTtQT%mm?@5Xb>sVU5Zo-H53bi2+DUQ3W|mvmGV8a*-f(V zkU#jraNas^dFGw7*~u3wZ@arO>H2%dkHg0;K%WXzYpLhOKw)?Xy%Ff&+TW(xS zxW6F1L0*;kZV3w;Zka!_$$-OypKsZ}XZgb{KCb?gbF0={8k@IpK$khuuMa!iduaWw zizALDEqbBr?WtF%US0eB`UmMl2jz9S)BMi3I}7s8FPoj3{&TzNye9j$bzSgJYU5*kGFHY@OlftGe_1v#QRb2=iFu~>p8U)e*3yiH)BlXC*!Wad|0f5`%bz)E!{Y7RfBLxQ zrzaz_oyB3UFYoS(y>db8<96M1^Rr&CYlocmve`JJ;T)!kZp*DHB9b{)Lw z+#fsg_j`YBu5|2=mIF8Jo)*2lN~=ZrZ+<>$!Tw&+Gn!oexow&M408^9^i}m|ol8w} zuCy&zckRcMUbn6ED?hIJJ7UktK`rXv?2t3>kADi3@*!@OASq_10&$Czm?9X?sHHwoZ7NFG|%*S-fS_?BzWQGP7T`s(jL=#rWCl zFSm^x`ht0F5KoHY-N^ zJn5xAOdPoO`YV&0{qSv-$`wW@_2@Xa;TK0crtYmas+Li|My2Zu_Kf)cyX{Zce>Lsn zrftSvzPUsh-ODMv_;$xSV`889{@*?Nv~Tpp!bLmdnxAdc?nvriM_RVLvBLP~+j2Xm zEcm&io^oY)t07;%aieV8DQN}YtgH8K!)d#os=Y7e`WsO*U%R_{e9j`P(f#*l9(bqJ z#dY8Kl9xsd{4)FVYR|MS=)CLq!JpJw^<}v&2Rn|hz3&=3+jQHqoW^PG@9xy@I1gqS zYc`(k_e;gHyKm=&HyZO-e!_~k5^^iglXeU|;Pjj_Ywqq<3G0px*&dT}{bj9o&0$aE zURrqg$baRri%vY(=gx@V5A0Ylr~2?ON*9zdns@$tQ_rcNS$QpX(w=7m(}m>TF=%zy<5G0qj5~s8)sX7mvVCT>4BeT*WDX+ z^IYY#v;G|1N58=F@Bmho4;DOry#*>a_Ciqc>nY>q#+Uzl?86KBzdgMDexs{z|B(CJp1eQOo_9Xme(v7h6OsF;v`YT= z(m10aTQ7HO?!zg!(sj?&S4Z!ha4+TlKaEDUF8ktd2bEW^tiJ!$hKuXwXLdPWBeVC! zYyG!=uzr1~Gj*dMcu%KZD|l2B(gICLHe@Z>1ZACnAw6$R?c8$-tO4tj*e9`9A9vp% zwz3K*!0X_}&uaenw8J#heZgQ6Wh#YN4zFDHjPFn?i}kcxb$mvPM~MvzP_?4B!Zleh zY`q=3Jlnfhf}4@XJ_wUFchnYiz&a;NHE*byfmb%fmoi?sb1S@J*{^-$o?}hIN)PXN z+b-{hU+~rm*G(m;s%mI~-k#VmDk0vz^E_MjxDjaNMGv|8D@*GTMSlf;(fc1Sma9Cj zVui1K1w&Y>=c$?N=JN;+#4{Qdmv z(^)@{M|a;H#%j73hOx)^AJyIV8LR>STU~d22J7Z_&R|dRf0p(AmBF6$xO+0ep$L@XlyPMNlHD8Bp*2T->dn6=u z>+YL7p4ISpEj!YEZvv|hDtF%m*3_f9zf54KJc@6}L^i_1di02oit6WUKAA1_R)~*D z?$W)EX&tZ0hX0?PhP*g9D`U*q(OHq2 z>~79tO?|WGvcX=~sn4^?{o;JL7O?hS_sBP472UTtvYM<@;SLX2!Xl~~I%T1{@-o)U zw{Z#U>19y~z4}LYcS|i}GhOK;mh4`}|Ai}&s;Nh+vK*-!N_ltXGFHuP{Wcqf?V0m7 z+v)p#EwemsMsipsx9(h4vtl9O^E*R#)Aq8e)ht0OpydlASQFp9lcN zSjl3;;NZ>gGtCpG>hAoF>~SxPOYWB(+t0USBa066NWOnILl5`*%F?x5XFMyf z7Jfv-ZI&{3p1E=OhWQkC8P?#!G1-YpSl; zD5oXX+|ju#!hQ1ud(2UE)6|GGtZ5c%U6#vDI+v%(MG88F{)HnIBw?sBh9qHE zLf3TL)QJ#$e~QFEy~KZt_Qv8S(>24CiKkV^#+!pw2)v+^2Ng?E6sn*lTQ*h3vJ``? zDXOm9#Dm;m?m@r*gIdF0S)rDg_`nt+R!q&N Jy9z-lgrbr}?piIela{_6g%G9lr zq{}jKp(@F?OoU)fryf)-O{cU9lo37S=oXE1E|~7SB$+Bz5DWzc71fYb;w?@~GY4zB zKQOufgYM@H4MMEgwx&@R+O}+vm{Bdol!~G{P)Jmy35g>v*ev1I!u&%FT7qE3rYWY_ ziY`R3C0RNNOcm-;Ww0jGG*(T^v2`j~m&8<54SZ@aG`J)g+ev~Ipf#GVnjjmPQ+g3RM*1YOE_(hiS)U1*;`40P}Cph7F5q*xfLhA`y( zOreUZCctdybDUPU9bwTDkcuu@)H4c#hVC&KqU#fWs%-NQ0FnL;X}Lr6Ax4#ru+ z)$m0Aa{ z0<{Ji2BIGrUMRO{B^rIsF*Gy)LJTBD!9Kht24J3_PRJ_>e$Mv4Mo({sXZ}ynybm(v}JZfrAAF zg?#6<)HCpbMYm4T9oeE44jS4riC_?;afb?)3~qAh8Wgl?Sw_#1gt`D)KU(Jg54vA6 zERzNyik@T%TY~m3C};^W1F5>8jIPKf0jhuhp&<%ns3n}3e?Mc%$|a%A(%KINQQ|_M z13#gAa@vxD{fte+L7os|z<^+P3VH?%4FSoT=wd~A9EfV9yMUy0969JVp|2IDC+rUj zkw8pqKe`Yat)L+6BWq}OmY|Gn(u|NS^r4bo<^G2YQNamAO_FKf=ESs9qBS9E2rc;8 zB0o9=ka$~js9*_k#OI$S_ZmVsi3XvD=0p|5gn;%ESw>Y3$|%Br7yyP8hC+*Nx_6wIj#*^c z#H~uG((oYWW@JqZt^GVF9ZpPvCtRRC!eU{1rD!PC#517P1&dMNbfHM87Ch+hKSd=N z3^jU=lR-?+0I{gMim7Y=+;3FDHvVq$t+U;=I7J?N?OuHiZ$pIu)jQ?a13vR_l1C0eJ z2o*yu0YjCp$r$F+RK)C+#0>lohL|o33^An%UE{>mTUdLG&>SVP*4~|fT3{F2U?4c=VeR7fHPFE3RQwgm>L*VX((7cm@dM9nt^4a40I79*hYh)!G+6cY8@=b6O37k`32{HNKX+;nHYHzt@(_GMn6U+v@1eE!PQU@n?m?G z9CuP7fPaE@U?>R2i%LSbli^j;?ST3<3cqmy<{xbM{U3B87B$**RGcknS%!7Oogb{j z53vq{DRfsbVk}YM3h^Hp;!cwggH$NXxJ0BC4h)66AH2XI(Sxg^@zP3U$PNxa!lDIi zOdbTo5?Tk|)4*(kq?m%LB4m!Dh;f8>Dg3d({U3BcG!!lsF#5*D3{eIbbV8Qk;*&NQ z@DuJ7FgOgk@b>RNPH`yKM2L>)7q-L_E)_U!NkGY)7`K-;9c&3uE0LjDj&L!+iD~1& z1n&`-jqo(}3|ff*HZb=UGQz|Szu#ckU*vv(4SH*>;1vtuYQ@6+8BJMStcYtit~o<3 z<}WLRG%W6ae!W^;kqXN#zptgrVD>6e0KzXNX#n$EPFj|6eJ;Xu3`HDT^;BFK(n+_9 zLnUp|$T^E5W88!Y%?Y>+@9GdQ6d!bo@gF}l(Ea2SEea?xRT8G;yl_#B&jAgcCGb~u vO0JE~s*;v5a!6MBcI_ft_sN(rBoeO$xcLRFNhJ&uaG_WJ$tOGaj4A*BSr0q* diff --git a/genlist.sh b/genlist.sh index ddc252c..73daa1d 100644 --- a/genlist.sh +++ b/genlist.sh @@ -1,6 +1,6 @@ #!/bin/bash # aes_tab.o is a pseudo object as it's made from aes.o and MPI is optional export a=`echo -n "src/ciphers/aes/aes_enc.o *(MPIOBJECT) " ; find . -type f | sort | grep "[.]/src" | grep "[.]c" | grep -v "sha224" | grep -v "sha384" | grep -v "aes_tab" | grep -v "twofish_tab" | grep -v "whirltab" | grep -v "dh_sys" | grep -v "ecc_sys" | grep -v "mpi[.]c" | grep -v "sober128tab" | sed -e 'sE\./EE' | sed -e 's/\.c/\.o/' | xargs` -./parsenames.pl OBJECTS "$a" +perl ./parsenames.pl OBJECTS "$a" export a=`find . -type f | grep [.]/src | grep [.]h | sed -e 'se\./ee' | xargs` -./parsenames.pl HEADERS "$a" +perl ./parsenames.pl HEADERS "$a" diff --git a/makefile b/makefile index 9d97805..7562570 100644 --- a/makefile +++ b/makefile @@ -4,7 +4,7 @@ # Modified by Clay Culver # The version -VERSION=1.00 +VERSION=1.01 # Compiler and Linker Names #CC=gcc @@ -15,20 +15,20 @@ VERSION=1.00 #ARFLAGS=r # Compilation flags. Note the += does not write over the user's CFLAGS! -CFLAGS += -c -I./src/headers/ -Wall -Wsign-compare -W -Wshadow +CFLAGS += -c -I./testprof/ -I./src/headers/ -Wall -Wsign-compare -W -Wshadow -Wno-unused-parameter # additional warnings (newer GCC 3.4 and higher) #CFLAGS += -Wsystem-headers -Wdeclaration-after-statement -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wmissing-prototypes \ # -Wmissing-declarations -Wpointer-arith # optimize for SPEED -#CFLAGS += -O3 -funroll-all-loops +CFLAGS += -O3 -funroll-loops # add -fomit-frame-pointer. hinders debugging! CFLAGS += -fomit-frame-pointer # optimize for SIZE -CFLAGS += -Os -DLTC_SMALL_CODE +#CFLAGS += -Os -DLTC_SMALL_CODE # older GCCs can't handle the "rotate with immediate" ROLc/RORc/etc macros # define this to help @@ -39,12 +39,15 @@ CFLAGS += -Os -DLTC_SMALL_CODE #Output filenames for various targets. LIBNAME=libtomcrypt.a +LIBTEST=testprof/libtomcrypt_prof.a HASH=hashsum CRYPT=encrypt SMALL=small PROF=x86_prof TV=tv_gen MULTI=multi +TIMING=timing +TEST=test #LIBPATH-The directory for libtomcrypt to be installed to. #INCPATH-The directory to install the header files for libtomcrypt. @@ -56,93 +59,94 @@ DATAPATH=/usr/share/doc/libtomcrypt/pdf #Who do we install as? USER=root -GROUP=root +GROUP=wheel #List of objects to compile. #Leave MPI built-in or force developer to link against libtommath? MPIOBJECT=src/misc/mpi/mpi.o - -OBJECTS=src/ciphers/aes/aes_enc.o $(MPIOBJECT) src/ciphers/aes/aes.o \ -src/ciphers/anubis.o src/ciphers/blowfish.o src/ciphers/cast5.o src/ciphers/des.o \ -src/ciphers/khazad.o src/ciphers/noekeon.o src/ciphers/rc2.o src/ciphers/rc5.o \ -src/ciphers/rc6.o src/ciphers/safer/safer.o src/ciphers/safer/safer_tab.o \ -src/ciphers/safer/saferp.o src/ciphers/skipjack.o src/ciphers/twofish/twofish.o \ -src/ciphers/xtea.o src/encauth/eax/eax_addheader.o src/encauth/eax/eax_decrypt.o \ -src/encauth/eax/eax_decrypt_verify_memory.o src/encauth/eax/eax_done.o \ -src/encauth/eax/eax_encrypt.o src/encauth/eax/eax_encrypt_authenticate_memory.o \ -src/encauth/eax/eax_init.o src/encauth/eax/eax_test.o \ -src/encauth/ocb/ocb_decrypt.o src/encauth/ocb/ocb_decrypt_verify_memory.o \ -src/encauth/ocb/ocb_done_decrypt.o src/encauth/ocb/ocb_done_encrypt.o \ -src/encauth/ocb/ocb_encrypt.o src/encauth/ocb/ocb_encrypt_authenticate_memory.o \ -src/encauth/ocb/ocb_init.o src/encauth/ocb/ocb_ntz.o \ -src/encauth/ocb/ocb_shift_xor.o src/encauth/ocb/ocb_test.o \ -src/encauth/ocb/s_ocb_done.o src/hashes/chc/chc.o src/hashes/helper/hash_file.o \ -src/hashes/helper/hash_filehandle.o src/hashes/helper/hash_memory.o \ -src/hashes/helper/hash_memory_multi.o src/hashes/md2.o src/hashes/md4.o \ -src/hashes/md5.o src/hashes/rmd128.o src/hashes/rmd160.o src/hashes/sha1.o \ -src/hashes/sha2/sha256.o src/hashes/sha2/sha512.o src/hashes/tiger.o \ -src/hashes/whirl/whirl.o src/mac/hmac/hmac_done.o src/mac/hmac/hmac_file.o \ -src/mac/hmac/hmac_init.o src/mac/hmac/hmac_memory.o \ -src/mac/hmac/hmac_memory_multi.o src/mac/hmac/hmac_process.o \ -src/mac/hmac/hmac_test.o src/mac/omac/omac_done.o src/mac/omac/omac_file.o \ -src/mac/omac/omac_init.o src/mac/omac/omac_memory.o \ -src/mac/omac/omac_memory_multi.o src/mac/omac/omac_process.o \ -src/mac/omac/omac_test.o src/mac/pmac/pmac_done.o src/mac/pmac/pmac_file.o \ -src/mac/pmac/pmac_init.o src/mac/pmac/pmac_memory.o \ -src/mac/pmac/pmac_memory_multi.o src/mac/pmac/pmac_ntz.o \ -src/mac/pmac/pmac_process.o src/mac/pmac/pmac_shift_xor.o src/mac/pmac/pmac_test.o \ -src/misc/base64/base64_decode.o src/misc/base64/base64_encode.o \ -src/misc/burn_stack.o src/misc/crypt/crypt.o src/misc/crypt/crypt_argchk.o \ -src/misc/crypt/crypt_cipher_descriptor.o src/misc/crypt/crypt_cipher_is_valid.o \ -src/misc/crypt/crypt_find_cipher.o src/misc/crypt/crypt_find_cipher_any.o \ -src/misc/crypt/crypt_find_cipher_id.o src/misc/crypt/crypt_find_hash.o \ -src/misc/crypt/crypt_find_hash_any.o src/misc/crypt/crypt_find_hash_id.o \ -src/misc/crypt/crypt_find_prng.o src/misc/crypt/crypt_hash_descriptor.o \ -src/misc/crypt/crypt_hash_is_valid.o src/misc/crypt/crypt_prng_descriptor.o \ -src/misc/crypt/crypt_prng_is_valid.o src/misc/crypt/crypt_register_cipher.o \ -src/misc/crypt/crypt_register_hash.o src/misc/crypt/crypt_register_prng.o \ -src/misc/crypt/crypt_unregister_cipher.o src/misc/crypt/crypt_unregister_hash.o \ -src/misc/crypt/crypt_unregister_prng.o src/misc/error_to_string.o \ -src/misc/mpi/is_prime.o src/misc/mpi/mpi_to_ltc_error.o src/misc/mpi/rand_prime.o \ -src/misc/pkcs5/pkcs_5_1.o src/misc/pkcs5/pkcs_5_2.o src/misc/zeromem.o \ -src/modes/cbc/cbc_decrypt.o src/modes/cbc/cbc_encrypt.o src/modes/cbc/cbc_getiv.o \ -src/modes/cbc/cbc_setiv.o src/modes/cbc/cbc_start.o src/modes/cfb/cfb_decrypt.o \ -src/modes/cfb/cfb_encrypt.o src/modes/cfb/cfb_getiv.o src/modes/cfb/cfb_setiv.o \ -src/modes/cfb/cfb_start.o src/modes/ctr/ctr_decrypt.o src/modes/ctr/ctr_encrypt.o \ +OBJECTS=src/ciphers/aes/aes_enc.o $(MPIOBJECT) src/ciphers/aes/aes.o src/ciphers/anubis.o \ +src/ciphers/blowfish.o src/ciphers/cast5.o src/ciphers/des.o src/ciphers/khazad.o src/ciphers/noekeon.o \ +src/ciphers/rc2.o src/ciphers/rc5.o src/ciphers/rc6.o src/ciphers/safer/safer.o \ +src/ciphers/safer/safer_tab.o src/ciphers/safer/saferp.o src/ciphers/skipjack.o \ +src/ciphers/twofish/twofish.o src/ciphers/xtea.o src/encauth/ccm/ccm_memory.o \ +src/encauth/ccm/ccm_test.o src/encauth/eax/eax_addheader.o src/encauth/eax/eax_decrypt.o \ +src/encauth/eax/eax_decrypt_verify_memory.o src/encauth/eax/eax_done.o src/encauth/eax/eax_encrypt.o \ +src/encauth/eax/eax_encrypt_authenticate_memory.o src/encauth/eax/eax_init.o \ +src/encauth/eax/eax_test.o src/encauth/gcm/gcm_add_aad.o src/encauth/gcm/gcm_add_iv.o \ +src/encauth/gcm/gcm_done.o src/encauth/gcm/gcm_gf_mult.o src/encauth/gcm/gcm_init.o \ +src/encauth/gcm/gcm_memory.o src/encauth/gcm/gcm_process.o src/encauth/gcm/gcm_reset.o \ +src/encauth/gcm/gcm_test.o src/encauth/ocb/ocb_decrypt.o src/encauth/ocb/ocb_decrypt_verify_memory.o \ +src/encauth/ocb/ocb_done_decrypt.o src/encauth/ocb/ocb_done_encrypt.o src/encauth/ocb/ocb_encrypt.o \ +src/encauth/ocb/ocb_encrypt_authenticate_memory.o src/encauth/ocb/ocb_init.o src/encauth/ocb/ocb_ntz.o \ +src/encauth/ocb/ocb_shift_xor.o src/encauth/ocb/ocb_test.o src/encauth/ocb/s_ocb_done.o \ +src/hashes/chc/chc.o src/hashes/helper/hash_file.o src/hashes/helper/hash_filehandle.o \ +src/hashes/helper/hash_memory.o src/hashes/helper/hash_memory_multi.o src/hashes/md2.o src/hashes/md4.o \ +src/hashes/md5.o src/hashes/rmd128.o src/hashes/rmd160.o src/hashes/sha1.o src/hashes/sha2/sha256.o \ +src/hashes/sha2/sha512.o src/hashes/tiger.o src/hashes/whirl/whirl.o src/mac/hmac/hmac_done.o \ +src/mac/hmac/hmac_file.o src/mac/hmac/hmac_init.o src/mac/hmac/hmac_memory.o \ +src/mac/hmac/hmac_memory_multi.o src/mac/hmac/hmac_process.o src/mac/hmac/hmac_test.o \ +src/mac/omac/omac_done.o src/mac/omac/omac_file.o src/mac/omac/omac_init.o src/mac/omac/omac_memory.o \ +src/mac/omac/omac_memory_multi.o src/mac/omac/omac_process.o src/mac/omac/omac_test.o \ +src/mac/pelican/pelican.o src/mac/pelican/pelican_memory.o src/mac/pelican/pelican_test.o \ +src/mac/pmac/pmac_done.o src/mac/pmac/pmac_file.o src/mac/pmac/pmac_init.o src/mac/pmac/pmac_memory.o \ +src/mac/pmac/pmac_memory_multi.o src/mac/pmac/pmac_ntz.o src/mac/pmac/pmac_process.o \ +src/mac/pmac/pmac_shift_xor.o src/mac/pmac/pmac_test.o src/misc/base64/base64_decode.o \ +src/misc/base64/base64_encode.o src/misc/burn_stack.o src/misc/crypt/crypt.o \ +src/misc/crypt/crypt_argchk.o src/misc/crypt/crypt_cipher_descriptor.o \ +src/misc/crypt/crypt_cipher_is_valid.o src/misc/crypt/crypt_find_cipher.o \ +src/misc/crypt/crypt_find_cipher_any.o src/misc/crypt/crypt_find_cipher_id.o \ +src/misc/crypt/crypt_find_hash.o src/misc/crypt/crypt_find_hash_any.o \ +src/misc/crypt/crypt_find_hash_id.o src/misc/crypt/crypt_find_prng.o \ +src/misc/crypt/crypt_hash_descriptor.o src/misc/crypt/crypt_hash_is_valid.o \ +src/misc/crypt/crypt_prng_descriptor.o src/misc/crypt/crypt_prng_is_valid.o \ +src/misc/crypt/crypt_register_cipher.o src/misc/crypt/crypt_register_hash.o \ +src/misc/crypt/crypt_register_prng.o src/misc/crypt/crypt_unregister_cipher.o \ +src/misc/crypt/crypt_unregister_hash.o src/misc/crypt/crypt_unregister_prng.o \ +src/misc/error_to_string.o src/misc/mpi/is_prime.o src/misc/mpi/mpi_to_ltc_error.o \ +src/misc/mpi/rand_prime.o src/misc/pkcs5/pkcs_5_1.o src/misc/pkcs5/pkcs_5_2.o src/misc/zeromem.o \ +src/modes/cbc/cbc_decrypt.o src/modes/cbc/cbc_done.o src/modes/cbc/cbc_encrypt.o \ +src/modes/cbc/cbc_getiv.o src/modes/cbc/cbc_setiv.o src/modes/cbc/cbc_start.o \ +src/modes/cfb/cfb_decrypt.o src/modes/cfb/cfb_done.o src/modes/cfb/cfb_encrypt.o \ +src/modes/cfb/cfb_getiv.o src/modes/cfb/cfb_setiv.o src/modes/cfb/cfb_start.o \ +src/modes/ctr/ctr_decrypt.o src/modes/ctr/ctr_done.o src/modes/ctr/ctr_encrypt.o \ src/modes/ctr/ctr_getiv.o src/modes/ctr/ctr_setiv.o src/modes/ctr/ctr_start.o \ -src/modes/ecb/ecb_decrypt.o src/modes/ecb/ecb_encrypt.o src/modes/ecb/ecb_start.o \ -src/modes/ofb/ofb_decrypt.o src/modes/ofb/ofb_encrypt.o src/modes/ofb/ofb_getiv.o \ -src/modes/ofb/ofb_setiv.o src/modes/ofb/ofb_start.o \ -src/pk/asn1/der/der_decode_integer.o src/pk/asn1/der/der_encode_integer.o \ +src/modes/ecb/ecb_decrypt.o src/modes/ecb/ecb_done.o src/modes/ecb/ecb_encrypt.o \ +src/modes/ecb/ecb_start.o src/modes/ofb/ofb_decrypt.o src/modes/ofb/ofb_done.o \ +src/modes/ofb/ofb_encrypt.o src/modes/ofb/ofb_getiv.o src/modes/ofb/ofb_setiv.o \ +src/modes/ofb/ofb_start.o src/pk/asn1/der/der_decode_integer.o src/pk/asn1/der/der_encode_integer.o \ src/pk/asn1/der/der_get_multi_integer.o src/pk/asn1/der/der_length_integer.o \ -src/pk/asn1/der/der_put_multi_integer.o src/pk/dh/dh.o src/pk/dsa/dsa_export.o \ -src/pk/dsa/dsa_free.o src/pk/dsa/dsa_import.o src/pk/dsa/dsa_make_key.o \ -src/pk/dsa/dsa_sign_hash.o src/pk/dsa/dsa_verify_hash.o \ -src/pk/dsa/dsa_verify_key.o src/pk/ecc/ecc.o src/pk/packet_store_header.o \ -src/pk/packet_valid_header.o src/pk/pkcs1/pkcs_1_i2osp.o \ -src/pk/pkcs1/pkcs_1_mgf1.o src/pk/pkcs1/pkcs_1_oaep_decode.o \ -src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o \ -src/pk/pkcs1/pkcs_1_pss_decode.o src/pk/pkcs1/pkcs_1_pss_encode.o \ -src/pk/pkcs1/pkcs_1_v15_es_decode.o src/pk/pkcs1/pkcs_1_v15_es_encode.o \ -src/pk/pkcs1/pkcs_1_v15_sa_decode.o src/pk/pkcs1/pkcs_1_v15_sa_encode.o \ -src/pk/rsa/rsa_decrypt_key.o src/pk/rsa/rsa_encrypt_key.o src/pk/rsa/rsa_export.o \ -src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o src/pk/rsa/rsa_import.o \ -src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_sign_hash.o \ -src/pk/rsa/rsa_v15_decrypt_key.o src/pk/rsa/rsa_v15_encrypt_key.o \ -src/pk/rsa/rsa_v15_sign_hash.o src/pk/rsa/rsa_v15_verify_hash.o \ -src/pk/rsa/rsa_verify_hash.o src/prngs/fortuna.o src/prngs/rc4.o \ -src/prngs/rng_get_bytes.o src/prngs/rng_make_prng.o src/prngs/sober128.o \ -src/prngs/sprng.o src/prngs/yarrow.o +src/pk/asn1/der/der_put_multi_integer.o src/pk/dh/dh.o src/pk/dsa/dsa_export.o src/pk/dsa/dsa_free.o \ +src/pk/dsa/dsa_import.o src/pk/dsa/dsa_make_key.o src/pk/dsa/dsa_sign_hash.o \ +src/pk/dsa/dsa_verify_hash.o src/pk/dsa/dsa_verify_key.o src/pk/ecc/ecc.o src/pk/packet_store_header.o \ +src/pk/packet_valid_header.o src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o \ +src/pk/pkcs1/pkcs_1_oaep_decode.o src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o \ +src/pk/pkcs1/pkcs_1_pss_decode.o src/pk/pkcs1/pkcs_1_pss_encode.o src/pk/pkcs1/pkcs_1_v15_es_decode.o \ +src/pk/pkcs1/pkcs_1_v15_es_encode.o src/pk/pkcs1/pkcs_1_v15_sa_decode.o \ +src/pk/pkcs1/pkcs_1_v15_sa_encode.o src/pk/rsa/rsa_decrypt_key.o src/pk/rsa/rsa_encrypt_key.o \ +src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o src/pk/rsa/rsa_import.o \ +src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_sign_hash.o src/pk/rsa/rsa_v15_decrypt_key.o \ +src/pk/rsa/rsa_v15_encrypt_key.o src/pk/rsa/rsa_v15_sign_hash.o src/pk/rsa/rsa_v15_verify_hash.o \ +src/pk/rsa/rsa_verify_hash.o src/prngs/fortuna.o src/prngs/rc4.o src/prngs/rng_get_bytes.o \ +src/prngs/rng_make_prng.o src/prngs/sober128.o src/prngs/sprng.o src/prngs/yarrow.o + +HEADERS=src/headers/tommath_superclass.h src/headers/tomcrypt_cfg.h \ +src/headers/tomcrypt_mac.h src/headers/tomcrypt_macros.h \ +src/headers/tomcrypt_custom.h src/headers/tomcrypt_argchk.h \ +src/headers/tomcrypt_cipher.h src/headers/tomcrypt_pk.h \ +src/headers/tommath_class.h src/headers/ltc_tommath.h src/headers/tomcrypt_hash.h \ +src/headers/tomcrypt_misc.h src/headers/tomcrypt.h src/headers/tomcrypt_pkcs.h \ +src/headers/tomcrypt_prng.h testprof/tomcrypt_test.h 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 MULTIS=demos/multi.o +TIMINGS=demos/timing.o +TESTS=demos/test.o #Files left over from making the crypt.pdf. LEFTOVERS=*.dvi *.log *.aux *.toc *.idx *.ilg *.ind *.out @@ -150,12 +154,6 @@ 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=src/headers/ltc_tommath.h src/headers/tomcrypt_cfg.h \ -src/headers/tomcrypt_misc.h src/headers/tomcrypt_prng.h src/headers/tomcrypt_cipher.h src/headers/tomcrypt_hash.h \ -src/headers/tomcrypt_macros.h src/headers/tomcrypt_pk.h src/headers/tomcrypt.h src/headers/tomcrypt_argchk.h \ -src/headers/tomcrypt_custom.h src/headers/tomcrypt_pkcs.h src/headers/tommath_class.h src/headers/tommath_superclass.h - #The default rule for make builds the libtomcrypt library. default:library @@ -173,7 +171,10 @@ src/hashes/sha2/sha512.o: src/hashes/sha2/sha512.c src/hashes/sha2/sha384.c src/hashes/sha2/sha256.o: src/hashes/sha2/sha256.c src/hashes/sha2/sha224.c #This rule makes the libtomcrypt library. -library: $(LIBNAME) +library: $(LIBTEST) $(LIBNAME) + +$(LIBTEST): + cd testprof ; CFLAGS="$(CFLAGS)" make $(LIBNAME): $(OBJECTS) $(AR) $(ARFLAGS) $@ $(OBJECTS) @@ -191,14 +192,18 @@ crypt: library $(CRYPTOBJECTS) small: library $(SMALLOBJECTS) $(CC) $(SMALLOBJECTS) $(LIBNAME) -o $(SMALL) $(WARN) -x86_prof: library $(PROFS) - $(CC) $(PROFS) $(LIBNAME) $(EXTRALIBS) -o $(PROF) - tv_gen: library $(TVS) $(CC) $(TVS) $(LIBNAME) $(EXTRALIBS) -o $(TV) multi: library $(MULTIS) - $(CC) $(MULTIS) $(LIBNAME) -o multi + $(CC) $(MULTIS) $(LIBNAME) -o $(MULTI) + +timing: library $(TIMINGS) + $(CC) $(TIMINGS) $(LIBTEST) $(LIBNAME) -o $(TIMING) + +test: library $(TESTS) + $(CC) $(TESTS) $(LIBTEST) $(LIBNAME) -o $(TEST) + #This rule installs the library and the header files. This must be run #as root in order to have a high enough permission to write to the correct @@ -227,10 +232,14 @@ clean: rm -f `find . -type f | grep "[.]obj" | xargs` rm -f `find . -type f | grep "[.]lib" | xargs` rm -f `find . -type f | grep "[.]exe" | xargs` + rm -f `find . -type f | grep "[.]gcda" | xargs` + rm -f `find . -type f | grep "[.]gcno" | xargs` + rm -f `find . -type f | grep "[.]il" | xargs` + rm -f `find . -type f | grep "[.]dyn" | xargs` + rm -f `find . -type f | grep "[.]dpi" | xargs` rm -rf `find . -type d | grep "[.]libs" | xargs` rm -f crypt.aux crypt.dvi crypt.idx crypt.ilg crypt.ind crypt.log crypt.toc - rm -f $(TV) $(PROF) $(SMALL) $(CRYPT) $(HASHSUM) $(MULTI) - cd demos/test ; make clean + rm -f $(TV) $(PROF) $(SMALL) $(CRYPT) $(HASHSUM) $(MULTI) $(TIMING) $(TEST) rm -rf doc/doxygen rm -f doc/*.pdf @@ -262,18 +271,15 @@ docdvi: crypt.tex makeindex crypt.idx latex crypt > /dev/null -#for GCC 3.4+ -profiled: - make clean - make CFLAGS="$(CFLAGS) -fprofile-generate" EXTRALIBS=-lgcov x86_prof - ./x86_prof - rm *.o *.a x86_prof - make CFLAGS="$(CFLAGS) -fprofile-use" EXTRALIBS=-lgcov x86_prof - #zipup the project (take that!) -zipup: clean docs +no_oops: clean + cd .. ; cvs commit + +zipup: no_oops docs cd .. ; rm -rf crypt* libtomcrypt-$(VERSION) ; mkdir libtomcrypt-$(VERSION) ; \ cp -R ./libtomcrypt/* ./libtomcrypt-$(VERSION)/ ; \ - tar -cjvf crypt-$(VERSION).tar.bz2 libtomcrypt-$(VERSION)/* ; \ - zip -9 -r crypt-$(VERSION).zip libtomcrypt-$(VERSION)/* ; \ - gpg -b -a crypt-$(VERSION).tar.bz2 ; gpg -b -a crypt-$(VERSION).zip + cd libtomcrypt-$(VERSION) ; rm -rf `find . -type d | grep CVS | xargs` ; cd .. ; \ + tar -cjvf crypt-$(VERSION).tar.bz2 libtomcrypt-$(VERSION) ; \ + zip -9r crypt-$(VERSION).zip libtomcrypt-$(VERSION) ; \ + gpg -b -a crypt-$(VERSION).tar.bz2 ; gpg -b -a crypt-$(VERSION).zip ; \ + mv -fv crypt* ~ ; rm -rf libtomcrypt-$(VERSION) diff --git a/makefile.cygwin_dll b/makefile.cygwin_dll deleted file mode 100644 index a1f3696..0000000 --- a/makefile.cygwin_dll +++ /dev/null @@ -1,117 +0,0 @@ -#makefile for Cygwin [makes a .dll] - -default: ltc_dll - - -# Compilation flags. Note the += does not write over the user's CFLAGS! -CFLAGS += -I./src/headers/ -Wall -Wsign-compare -W -Wno-unused -Wshadow -mno-cygwin -DWIN32 -DLTC_NO_ROLC - -# optimize for SPEED -CFLAGS += -O3 -funroll-all-loops - -#add -fomit-frame-pointer. v3.2 is buggy for certain platforms! -CFLAGS += -fomit-frame-pointer - -# optimize for SIZE -#CFLAGS += -Os - -#Leave MPI built-in or force developer to link against libtommath? -MPIOBJECT=src/misc/mpi/mpi.o - -OBJECTS=src/ciphers/aes/aes_enc.o $(MPIOBJECT) src/ciphers/aes/aes.o \ -src/ciphers/anubis.o src/ciphers/blowfish.o src/ciphers/cast5.o src/ciphers/des.o \ -src/ciphers/khazad.o src/ciphers/noekeon.o src/ciphers/rc2.o src/ciphers/rc5.o \ -src/ciphers/rc6.o src/ciphers/safer/safer.o src/ciphers/safer/safer_tab.o \ -src/ciphers/safer/saferp.o src/ciphers/skipjack.o src/ciphers/twofish/twofish.o \ -src/ciphers/xtea.o src/encauth/eax/eax_addheader.o src/encauth/eax/eax_decrypt.o \ -src/encauth/eax/eax_decrypt_verify_memory.o src/encauth/eax/eax_done.o \ -src/encauth/eax/eax_encrypt.o src/encauth/eax/eax_encrypt_authenticate_memory.o \ -src/encauth/eax/eax_init.o src/encauth/eax/eax_test.o \ -src/encauth/ocb/ocb_decrypt.o src/encauth/ocb/ocb_decrypt_verify_memory.o \ -src/encauth/ocb/ocb_done_decrypt.o src/encauth/ocb/ocb_done_encrypt.o \ -src/encauth/ocb/ocb_encrypt.o src/encauth/ocb/ocb_encrypt_authenticate_memory.o \ -src/encauth/ocb/ocb_init.o src/encauth/ocb/ocb_ntz.o \ -src/encauth/ocb/ocb_shift_xor.o src/encauth/ocb/ocb_test.o \ -src/encauth/ocb/s_ocb_done.o src/hashes/chc/chc.o src/hashes/helper/hash_file.o \ -src/hashes/helper/hash_filehandle.o src/hashes/helper/hash_memory.o \ -src/hashes/helper/hash_memory_multi.o src/hashes/md2.o src/hashes/md4.o \ -src/hashes/md5.o src/hashes/rmd128.o src/hashes/rmd160.o src/hashes/sha1.o \ -src/hashes/sha2/sha256.o src/hashes/sha2/sha512.o src/hashes/tiger.o \ -src/hashes/whirl/whirl.o src/mac/hmac/hmac_done.o src/mac/hmac/hmac_file.o \ -src/mac/hmac/hmac_init.o src/mac/hmac/hmac_memory.o \ -src/mac/hmac/hmac_memory_multi.o src/mac/hmac/hmac_process.o \ -src/mac/hmac/hmac_test.o src/mac/omac/omac_done.o src/mac/omac/omac_file.o \ -src/mac/omac/omac_init.o src/mac/omac/omac_memory.o \ -src/mac/omac/omac_memory_multi.o src/mac/omac/omac_process.o \ -src/mac/omac/omac_test.o src/mac/pmac/pmac_done.o src/mac/pmac/pmac_file.o \ -src/mac/pmac/pmac_init.o src/mac/pmac/pmac_memory.o \ -src/mac/pmac/pmac_memory_multi.o src/mac/pmac/pmac_ntz.o \ -src/mac/pmac/pmac_process.o src/mac/pmac/pmac_shift_xor.o src/mac/pmac/pmac_test.o \ -src/misc/base64/base64_decode.o src/misc/base64/base64_encode.o \ -src/misc/burn_stack.o src/misc/crypt/crypt.o src/misc/crypt/crypt_argchk.o \ -src/misc/crypt/crypt_cipher_descriptor.o src/misc/crypt/crypt_cipher_is_valid.o \ -src/misc/crypt/crypt_find_cipher.o src/misc/crypt/crypt_find_cipher_any.o \ -src/misc/crypt/crypt_find_cipher_id.o src/misc/crypt/crypt_find_hash.o \ -src/misc/crypt/crypt_find_hash_any.o src/misc/crypt/crypt_find_hash_id.o \ -src/misc/crypt/crypt_find_prng.o src/misc/crypt/crypt_hash_descriptor.o \ -src/misc/crypt/crypt_hash_is_valid.o src/misc/crypt/crypt_prng_descriptor.o \ -src/misc/crypt/crypt_prng_is_valid.o src/misc/crypt/crypt_register_cipher.o \ -src/misc/crypt/crypt_register_hash.o src/misc/crypt/crypt_register_prng.o \ -src/misc/crypt/crypt_unregister_cipher.o src/misc/crypt/crypt_unregister_hash.o \ -src/misc/crypt/crypt_unregister_prng.o src/misc/error_to_string.o \ -src/misc/mpi/is_prime.o src/misc/mpi/mpi_to_ltc_error.o src/misc/mpi/rand_prime.o \ -src/misc/pkcs5/pkcs_5_1.o src/misc/pkcs5/pkcs_5_2.o src/misc/zeromem.o \ -src/modes/cbc/cbc_decrypt.o src/modes/cbc/cbc_encrypt.o src/modes/cbc/cbc_getiv.o \ -src/modes/cbc/cbc_setiv.o src/modes/cbc/cbc_start.o src/modes/cfb/cfb_decrypt.o \ -src/modes/cfb/cfb_encrypt.o src/modes/cfb/cfb_getiv.o src/modes/cfb/cfb_setiv.o \ -src/modes/cfb/cfb_start.o src/modes/ctr/ctr_decrypt.o src/modes/ctr/ctr_encrypt.o \ -src/modes/ctr/ctr_getiv.o src/modes/ctr/ctr_setiv.o src/modes/ctr/ctr_start.o \ -src/modes/ecb/ecb_decrypt.o src/modes/ecb/ecb_encrypt.o src/modes/ecb/ecb_start.o \ -src/modes/ofb/ofb_decrypt.o src/modes/ofb/ofb_encrypt.o src/modes/ofb/ofb_getiv.o \ -src/modes/ofb/ofb_setiv.o src/modes/ofb/ofb_start.o \ -src/pk/asn1/der/der_decode_integer.o src/pk/asn1/der/der_encode_integer.o \ -src/pk/asn1/der/der_get_multi_integer.o src/pk/asn1/der/der_length_integer.o \ -src/pk/asn1/der/der_put_multi_integer.o src/pk/dh/dh.o src/pk/dsa/dsa_export.o \ -src/pk/dsa/dsa_free.o src/pk/dsa/dsa_import.o src/pk/dsa/dsa_make_key.o \ -src/pk/dsa/dsa_sign_hash.o src/pk/dsa/dsa_verify_hash.o \ -src/pk/dsa/dsa_verify_key.o src/pk/ecc/ecc.o src/pk/packet_store_header.o \ -src/pk/packet_valid_header.o src/pk/pkcs1/pkcs_1_i2osp.o \ -src/pk/pkcs1/pkcs_1_mgf1.o src/pk/pkcs1/pkcs_1_oaep_decode.o \ -src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o \ -src/pk/pkcs1/pkcs_1_pss_decode.o src/pk/pkcs1/pkcs_1_pss_encode.o \ -src/pk/pkcs1/pkcs_1_v15_es_decode.o src/pk/pkcs1/pkcs_1_v15_es_encode.o \ -src/pk/pkcs1/pkcs_1_v15_sa_decode.o src/pk/pkcs1/pkcs_1_v15_sa_encode.o \ -src/pk/rsa/rsa_decrypt_key.o src/pk/rsa/rsa_encrypt_key.o src/pk/rsa/rsa_export.o \ -src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o src/pk/rsa/rsa_import.o \ -src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_sign_hash.o \ -src/pk/rsa/rsa_v15_decrypt_key.o src/pk/rsa/rsa_v15_encrypt_key.o \ -src/pk/rsa/rsa_v15_sign_hash.o src/pk/rsa/rsa_v15_verify_hash.o \ -src/pk/rsa/rsa_verify_hash.o src/prngs/fortuna.o src/prngs/rc4.o \ -src/prngs/rng_get_bytes.o src/prngs/rng_make_prng.o src/prngs/sober128.o \ -src/prngs/sprng.o src/prngs/yarrow.o - -#Header files used by libtomcrypt. -HEADERS=src/headers/ltc_tommath.h src/headers/tomcrypt_cfg.h \ -src/headers/tomcrypt_misc.h src/headers/tomcrypt_prng.h src/headers/tomcrypt_cipher.h src/headers/tomcrypt_hash.h \ -src/headers/tomcrypt_macros.h src/headers/tomcrypt_pk.h src/headers/tomcrypt.h src/headers/tomcrypt_argchk.h \ -src/headers/tomcrypt_custom.h src/headers/tomcrypt_pkcs.h src/headers/tommath_class.h src/headers/tommath_superclass.h - -#ciphers come in two flavours... enc+dec and enc -src/ciphers/aes/aes_enc.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c - $(CC) $(CFLAGS) -DENCRYPT_ONLY -c src/ciphers/aes/aes.c -o src/ciphers/aes/aes_enc.o - -#These are the rules to make certain object files. -src/ciphers/aes/aes.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c -src/ciphers/twofish/twofish.o: src/ciphers/twofish/twofish.c src/ciphers/twofish/twofish_tab.c -src/hashes/whirl/whirl.o: src/hashes/whirl/whirl.c src/hashes/whirl/whirltab.c -src/pk/ecc/ecc.o: src/pk/ecc/ecc.c src/pk/ecc/ecc_sys.c -src/pk/dh/dh.o: src/pk/dh/dh.c src/pk/dh/dh_sys.c -src/hashes/sha2/sha512.o: src/hashes/sha2/sha512.c src/hashes/sha2/sha384.c -src/hashes/sha2/sha256.o: src/hashes/sha2/sha256.c src/hashes/sha2/sha224.c - -ltc_dll: $(OBJECTS) $(MPIOBJECT) - gcc -mno-cygwin -mdll -o libtomcrypt.dll -Wl,--out-implib=libtomcrypt.dll.a -Wl,--export-all-symbols `find . -type f | grep [.]o | xargs` -ladvapi32 - ranlib libtomcrypt.dll.a - cp -fv src/headers/* /usr/include - cp -fv *.a /usr/lib - cp -fv *.dll /usr/bin diff --git a/makefile.icc b/makefile.icc index cd01c0b..41848dc 100644 --- a/makefile.icc +++ b/makefile.icc @@ -41,7 +41,7 @@ default:library # B - Blend of P4 and PM [mobile] # # Default to just generic max opts -CFLAGS += -O3 -xN -ip +CFLAGS += -O3 -xP -ip # want to see stuff? #CFLAGS += -opt_report @@ -50,11 +50,15 @@ CFLAGS += -O3 -xN -ip #Output filenames for various targets. LIBNAME=libtomcrypt.a +LIBTEST=testprof/libtomcrypt_prof.a HASH=hashsum CRYPT=encrypt SMALL=small PROF=x86_prof TV=tv_gen +MULTI=multi +TIMING=timing +TEST=test #LIBPATH-The directory for libtomcrypt to be installed to. #INCPATH-The directory to install the header files for libtomcrypt. @@ -69,77 +73,78 @@ DATAPATH=/usr/share/doc/libtomcrypt/pdf #Leave MPI built-in or force developer to link against libtommath? MPIOBJECT=src/misc/mpi/mpi.o -OBJECTS=src/ciphers/aes/aes_enc.o $(MPIOBJECT) src/ciphers/aes/aes.o \ -src/ciphers/anubis.o src/ciphers/blowfish.o src/ciphers/cast5.o src/ciphers/des.o \ -src/ciphers/khazad.o src/ciphers/noekeon.o src/ciphers/rc2.o src/ciphers/rc5.o \ -src/ciphers/rc6.o src/ciphers/safer/safer.o src/ciphers/safer/safer_tab.o \ -src/ciphers/safer/saferp.o src/ciphers/skipjack.o src/ciphers/twofish/twofish.o \ -src/ciphers/xtea.o src/encauth/eax/eax_addheader.o src/encauth/eax/eax_decrypt.o \ -src/encauth/eax/eax_decrypt_verify_memory.o src/encauth/eax/eax_done.o \ -src/encauth/eax/eax_encrypt.o src/encauth/eax/eax_encrypt_authenticate_memory.o \ -src/encauth/eax/eax_init.o src/encauth/eax/eax_test.o \ -src/encauth/ocb/ocb_decrypt.o src/encauth/ocb/ocb_decrypt_verify_memory.o \ -src/encauth/ocb/ocb_done_decrypt.o src/encauth/ocb/ocb_done_encrypt.o \ -src/encauth/ocb/ocb_encrypt.o src/encauth/ocb/ocb_encrypt_authenticate_memory.o \ -src/encauth/ocb/ocb_init.o src/encauth/ocb/ocb_ntz.o \ -src/encauth/ocb/ocb_shift_xor.o src/encauth/ocb/ocb_test.o \ -src/encauth/ocb/s_ocb_done.o src/hashes/chc/chc.o src/hashes/helper/hash_file.o \ -src/hashes/helper/hash_filehandle.o src/hashes/helper/hash_memory.o \ -src/hashes/helper/hash_memory_multi.o src/hashes/md2.o src/hashes/md4.o \ -src/hashes/md5.o src/hashes/rmd128.o src/hashes/rmd160.o src/hashes/sha1.o \ -src/hashes/sha2/sha256.o src/hashes/sha2/sha512.o src/hashes/tiger.o \ -src/hashes/whirl/whirl.o src/mac/hmac/hmac_done.o src/mac/hmac/hmac_file.o \ -src/mac/hmac/hmac_init.o src/mac/hmac/hmac_memory.o \ -src/mac/hmac/hmac_memory_multi.o src/mac/hmac/hmac_process.o \ -src/mac/hmac/hmac_test.o src/mac/omac/omac_done.o src/mac/omac/omac_file.o \ -src/mac/omac/omac_init.o src/mac/omac/omac_memory.o \ -src/mac/omac/omac_memory_multi.o src/mac/omac/omac_process.o \ -src/mac/omac/omac_test.o src/mac/pmac/pmac_done.o src/mac/pmac/pmac_file.o \ -src/mac/pmac/pmac_init.o src/mac/pmac/pmac_memory.o \ -src/mac/pmac/pmac_memory_multi.o src/mac/pmac/pmac_ntz.o \ -src/mac/pmac/pmac_process.o src/mac/pmac/pmac_shift_xor.o src/mac/pmac/pmac_test.o \ -src/misc/base64/base64_decode.o src/misc/base64/base64_encode.o \ -src/misc/burn_stack.o src/misc/crypt/crypt.o src/misc/crypt/crypt_argchk.o \ -src/misc/crypt/crypt_cipher_descriptor.o src/misc/crypt/crypt_cipher_is_valid.o \ -src/misc/crypt/crypt_find_cipher.o src/misc/crypt/crypt_find_cipher_any.o \ -src/misc/crypt/crypt_find_cipher_id.o src/misc/crypt/crypt_find_hash.o \ -src/misc/crypt/crypt_find_hash_any.o src/misc/crypt/crypt_find_hash_id.o \ -src/misc/crypt/crypt_find_prng.o src/misc/crypt/crypt_hash_descriptor.o \ -src/misc/crypt/crypt_hash_is_valid.o src/misc/crypt/crypt_prng_descriptor.o \ -src/misc/crypt/crypt_prng_is_valid.o src/misc/crypt/crypt_register_cipher.o \ -src/misc/crypt/crypt_register_hash.o src/misc/crypt/crypt_register_prng.o \ -src/misc/crypt/crypt_unregister_cipher.o src/misc/crypt/crypt_unregister_hash.o \ -src/misc/crypt/crypt_unregister_prng.o src/misc/error_to_string.o \ -src/misc/mpi/is_prime.o src/misc/mpi/mpi_to_ltc_error.o src/misc/mpi/rand_prime.o \ -src/misc/pkcs5/pkcs_5_1.o src/misc/pkcs5/pkcs_5_2.o src/misc/zeromem.o \ -src/modes/cbc/cbc_decrypt.o src/modes/cbc/cbc_encrypt.o src/modes/cbc/cbc_getiv.o \ -src/modes/cbc/cbc_setiv.o src/modes/cbc/cbc_start.o src/modes/cfb/cfb_decrypt.o \ -src/modes/cfb/cfb_encrypt.o src/modes/cfb/cfb_getiv.o src/modes/cfb/cfb_setiv.o \ -src/modes/cfb/cfb_start.o src/modes/ctr/ctr_decrypt.o src/modes/ctr/ctr_encrypt.o \ +OBJECTS=src/ciphers/aes/aes_enc.o $(MPIOBJECT) src/ciphers/aes/aes.o src/ciphers/anubis.o \ +src/ciphers/blowfish.o src/ciphers/cast5.o src/ciphers/des.o src/ciphers/khazad.o src/ciphers/noekeon.o \ +src/ciphers/rc2.o src/ciphers/rc5.o src/ciphers/rc6.o src/ciphers/safer/safer.o \ +src/ciphers/safer/safer_tab.o src/ciphers/safer/saferp.o src/ciphers/skipjack.o \ +src/ciphers/twofish/twofish.o src/ciphers/xtea.o src/encauth/ccm/ccm_memory.o \ +src/encauth/ccm/ccm_test.o src/encauth/eax/eax_addheader.o src/encauth/eax/eax_decrypt.o \ +src/encauth/eax/eax_decrypt_verify_memory.o src/encauth/eax/eax_done.o src/encauth/eax/eax_encrypt.o \ +src/encauth/eax/eax_encrypt_authenticate_memory.o src/encauth/eax/eax_init.o \ +src/encauth/eax/eax_test.o src/encauth/gcm/gcm_add_aad.o src/encauth/gcm/gcm_add_iv.o \ +src/encauth/gcm/gcm_done.o src/encauth/gcm/gcm_gf_mult.o src/encauth/gcm/gcm_init.o \ +src/encauth/gcm/gcm_memory.o src/encauth/gcm/gcm_process.o src/encauth/gcm/gcm_reset.o \ +src/encauth/gcm/gcm_test.o src/encauth/ocb/ocb_decrypt.o src/encauth/ocb/ocb_decrypt_verify_memory.o \ +src/encauth/ocb/ocb_done_decrypt.o src/encauth/ocb/ocb_done_encrypt.o src/encauth/ocb/ocb_encrypt.o \ +src/encauth/ocb/ocb_encrypt_authenticate_memory.o src/encauth/ocb/ocb_init.o src/encauth/ocb/ocb_ntz.o \ +src/encauth/ocb/ocb_shift_xor.o src/encauth/ocb/ocb_test.o src/encauth/ocb/s_ocb_done.o \ +src/hashes/chc/chc.o src/hashes/helper/hash_file.o src/hashes/helper/hash_filehandle.o \ +src/hashes/helper/hash_memory.o src/hashes/helper/hash_memory_multi.o src/hashes/md2.o src/hashes/md4.o \ +src/hashes/md5.o src/hashes/rmd128.o src/hashes/rmd160.o src/hashes/sha1.o src/hashes/sha2/sha256.o \ +src/hashes/sha2/sha512.o src/hashes/tiger.o src/hashes/whirl/whirl.o src/mac/hmac/hmac_done.o \ +src/mac/hmac/hmac_file.o src/mac/hmac/hmac_init.o src/mac/hmac/hmac_memory.o \ +src/mac/hmac/hmac_memory_multi.o src/mac/hmac/hmac_process.o src/mac/hmac/hmac_test.o \ +src/mac/omac/omac_done.o src/mac/omac/omac_file.o src/mac/omac/omac_init.o src/mac/omac/omac_memory.o \ +src/mac/omac/omac_memory_multi.o src/mac/omac/omac_process.o src/mac/omac/omac_test.o \ +src/mac/pelican/pelican.o src/mac/pelican/pelican_memory.o src/mac/pelican/pelican_test.o \ +src/mac/pmac/pmac_done.o src/mac/pmac/pmac_file.o src/mac/pmac/pmac_init.o src/mac/pmac/pmac_memory.o \ +src/mac/pmac/pmac_memory_multi.o src/mac/pmac/pmac_ntz.o src/mac/pmac/pmac_process.o \ +src/mac/pmac/pmac_shift_xor.o src/mac/pmac/pmac_test.o src/misc/base64/base64_decode.o \ +src/misc/base64/base64_encode.o src/misc/burn_stack.o src/misc/crypt/crypt.o \ +src/misc/crypt/crypt_argchk.o src/misc/crypt/crypt_cipher_descriptor.o \ +src/misc/crypt/crypt_cipher_is_valid.o src/misc/crypt/crypt_find_cipher.o \ +src/misc/crypt/crypt_find_cipher_any.o src/misc/crypt/crypt_find_cipher_id.o \ +src/misc/crypt/crypt_find_hash.o src/misc/crypt/crypt_find_hash_any.o \ +src/misc/crypt/crypt_find_hash_id.o src/misc/crypt/crypt_find_prng.o \ +src/misc/crypt/crypt_hash_descriptor.o src/misc/crypt/crypt_hash_is_valid.o \ +src/misc/crypt/crypt_prng_descriptor.o src/misc/crypt/crypt_prng_is_valid.o \ +src/misc/crypt/crypt_register_cipher.o src/misc/crypt/crypt_register_hash.o \ +src/misc/crypt/crypt_register_prng.o src/misc/crypt/crypt_unregister_cipher.o \ +src/misc/crypt/crypt_unregister_hash.o src/misc/crypt/crypt_unregister_prng.o \ +src/misc/error_to_string.o src/misc/mpi/is_prime.o src/misc/mpi/mpi_to_ltc_error.o \ +src/misc/mpi/rand_prime.o src/misc/pkcs5/pkcs_5_1.o src/misc/pkcs5/pkcs_5_2.o src/misc/zeromem.o \ +src/modes/cbc/cbc_decrypt.o src/modes/cbc/cbc_done.o src/modes/cbc/cbc_encrypt.o \ +src/modes/cbc/cbc_getiv.o src/modes/cbc/cbc_setiv.o src/modes/cbc/cbc_start.o \ +src/modes/cfb/cfb_decrypt.o src/modes/cfb/cfb_done.o src/modes/cfb/cfb_encrypt.o \ +src/modes/cfb/cfb_getiv.o src/modes/cfb/cfb_setiv.o src/modes/cfb/cfb_start.o \ +src/modes/ctr/ctr_decrypt.o src/modes/ctr/ctr_done.o src/modes/ctr/ctr_encrypt.o \ src/modes/ctr/ctr_getiv.o src/modes/ctr/ctr_setiv.o src/modes/ctr/ctr_start.o \ -src/modes/ecb/ecb_decrypt.o src/modes/ecb/ecb_encrypt.o src/modes/ecb/ecb_start.o \ -src/modes/ofb/ofb_decrypt.o src/modes/ofb/ofb_encrypt.o src/modes/ofb/ofb_getiv.o \ -src/modes/ofb/ofb_setiv.o src/modes/ofb/ofb_start.o \ -src/pk/asn1/der/der_decode_integer.o src/pk/asn1/der/der_encode_integer.o \ +src/modes/ecb/ecb_decrypt.o src/modes/ecb/ecb_done.o src/modes/ecb/ecb_encrypt.o \ +src/modes/ecb/ecb_start.o src/modes/ofb/ofb_decrypt.o src/modes/ofb/ofb_done.o \ +src/modes/ofb/ofb_encrypt.o src/modes/ofb/ofb_getiv.o src/modes/ofb/ofb_setiv.o \ +src/modes/ofb/ofb_start.o src/pk/asn1/der/der_decode_integer.o src/pk/asn1/der/der_encode_integer.o \ src/pk/asn1/der/der_get_multi_integer.o src/pk/asn1/der/der_length_integer.o \ -src/pk/asn1/der/der_put_multi_integer.o src/pk/dh/dh.o src/pk/dsa/dsa_export.o \ -src/pk/dsa/dsa_free.o src/pk/dsa/dsa_import.o src/pk/dsa/dsa_make_key.o \ -src/pk/dsa/dsa_sign_hash.o src/pk/dsa/dsa_verify_hash.o \ -src/pk/dsa/dsa_verify_key.o src/pk/ecc/ecc.o src/pk/packet_store_header.o \ -src/pk/packet_valid_header.o src/pk/pkcs1/pkcs_1_i2osp.o \ -src/pk/pkcs1/pkcs_1_mgf1.o src/pk/pkcs1/pkcs_1_oaep_decode.o \ -src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o \ -src/pk/pkcs1/pkcs_1_pss_decode.o src/pk/pkcs1/pkcs_1_pss_encode.o \ -src/pk/pkcs1/pkcs_1_v15_es_decode.o src/pk/pkcs1/pkcs_1_v15_es_encode.o \ -src/pk/pkcs1/pkcs_1_v15_sa_decode.o src/pk/pkcs1/pkcs_1_v15_sa_encode.o \ -src/pk/rsa/rsa_decrypt_key.o src/pk/rsa/rsa_encrypt_key.o src/pk/rsa/rsa_export.o \ -src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o src/pk/rsa/rsa_import.o \ -src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_sign_hash.o \ -src/pk/rsa/rsa_v15_decrypt_key.o src/pk/rsa/rsa_v15_encrypt_key.o \ -src/pk/rsa/rsa_v15_sign_hash.o src/pk/rsa/rsa_v15_verify_hash.o \ -src/pk/rsa/rsa_verify_hash.o src/prngs/fortuna.o src/prngs/rc4.o \ -src/prngs/rng_get_bytes.o src/prngs/rng_make_prng.o src/prngs/sober128.o \ -src/prngs/sprng.o src/prngs/yarrow.o +src/pk/asn1/der/der_put_multi_integer.o src/pk/dh/dh.o src/pk/dsa/dsa_export.o src/pk/dsa/dsa_free.o \ +src/pk/dsa/dsa_import.o src/pk/dsa/dsa_make_key.o src/pk/dsa/dsa_sign_hash.o \ +src/pk/dsa/dsa_verify_hash.o src/pk/dsa/dsa_verify_key.o src/pk/ecc/ecc.o src/pk/packet_store_header.o \ +src/pk/packet_valid_header.o src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o \ +src/pk/pkcs1/pkcs_1_oaep_decode.o src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o \ +src/pk/pkcs1/pkcs_1_pss_decode.o src/pk/pkcs1/pkcs_1_pss_encode.o src/pk/pkcs1/pkcs_1_v15_es_decode.o \ +src/pk/pkcs1/pkcs_1_v15_es_encode.o src/pk/pkcs1/pkcs_1_v15_sa_decode.o \ +src/pk/pkcs1/pkcs_1_v15_sa_encode.o src/pk/rsa/rsa_decrypt_key.o src/pk/rsa/rsa_encrypt_key.o \ +src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o src/pk/rsa/rsa_import.o \ +src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_sign_hash.o src/pk/rsa/rsa_v15_decrypt_key.o \ +src/pk/rsa/rsa_v15_encrypt_key.o src/pk/rsa/rsa_v15_sign_hash.o src/pk/rsa/rsa_v15_verify_hash.o \ +src/pk/rsa/rsa_verify_hash.o src/prngs/fortuna.o src/prngs/rc4.o src/prngs/rng_get_bytes.o \ +src/prngs/rng_make_prng.o src/prngs/sober128.o src/prngs/sprng.o src/prngs/yarrow.o + +HEADERS=src/headers/tommath_superclass.h src/headers/tomcrypt_cfg.h \ +src/headers/tomcrypt_mac.h src/headers/tomcrypt_macros.h \ +src/headers/tomcrypt_custom.h src/headers/tomcrypt_argchk.h \ +src/headers/tomcrypt_cipher.h src/headers/tomcrypt_pk.h \ +src/headers/tommath_class.h src/headers/ltc_tommath.h src/headers/tomcrypt_hash.h \ +src/headers/tomcrypt_misc.h src/headers/tomcrypt.h src/headers/tomcrypt_pkcs.h \ +src/headers/tomcrypt_prng.h testprof/tomcrypt_test.h #ciphers come in two flavours... enc+dec and enc aes_enc.o: aes.c aes_tab.c @@ -148,8 +153,9 @@ aes_enc.o: aes.c aes_tab.c HASHOBJECTS=demos/hashsum.o CRYPTOBJECTS=demos/encrypt.o SMALLOBJECTS=demos/small.o -PROFS=demos/x86_prof.o TVS=demos/tv_gen.o +TIMINGS=demos/timing.o +TESTS=demos/test.o #Files left over from making the crypt.pdf. LEFTOVERS=*.dvi *.log *.aux *.toc *.idx *.ilg *.ind @@ -157,12 +163,6 @@ LEFTOVERS=*.dvi *.log *.aux *.toc *.idx *.ilg *.ind #Compressed filenames COMPRESSED=crypt.tar.bz2 crypt.zip crypt.tar.gz -#Header files used by libtomcrypt. -HEADERS=src/headers/ltc_tommath.h src/headers/tomcrypt_cfg.h \ -src/headers/tomcrypt_misc.h src/headers/tomcrypt_prng.h src/headers/tomcrypt_cipher.h src/headers/tomcrypt_hash.h \ -src/headers/tomcrypt_macros.h src/headers/tomcrypt_pk.h src/headers/tomcrypt.h src/headers/tomcrypt_argchk.h \ -src/headers/tomcrypt_custom.h src/headers/tomcrypt_pkcs.h src/headers/tommath_class.h src/headers/tommath_superclass.h - #ciphers come in two flavours... enc+dec and enc src/ciphers/aes/aes_enc.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c $(CC) $(CFLAGS) -DENCRYPT_ONLY -c src/ciphers/aes/aes.c -o src/ciphers/aes/aes_enc.o @@ -177,7 +177,10 @@ src/hashes/sha2/sha512.o: src/hashes/sha2/sha512.c src/hashes/sha2/sha384.c src/hashes/sha2/sha256.o: src/hashes/sha2/sha256.c src/hashes/sha2/sha224.c #This rule makes the libtomcrypt library. -library: $(LIBNAME) +library: $(LIBTEST) $(LIBNAME) + +$(LIBTEST): + cd testprof ; make -f makefile.icc $(LIBNAME): $(OBJECTS) $(AR) $(ARFLAGS) $@ $(OBJECTS) @@ -195,19 +198,14 @@ crypt: library $(CRYPTOBJECTS) small: library $(SMALLOBJECTS) $(CC) $(SMALLOBJECTS) $(LIBNAME) -o $(SMALL) $(WARN) -x86_prof: library $(PROFS) - $(CC) $(PROFS) $(LIBNAME) -o $(PROF) - tv_gen: library $(TVS) $(CC) $(TVS) $(LIBNAME) -o $(TV) -profiled: - make clean - make -f makefile.icc CFLAGS="$(CFLAGS) -prof_gen" x86_prof - ./x86_prof - rm *.o *.a x86_prof - make -f makefile.icc CFLAGS="$(CFLAGS) -prof_use" x86_prof +timing: library $(TIMINGS) + $(CC) $(TIMINGS) $(LIBTEST) $(LIBNAME) -o $(TIMING) +test: library $(TESTS) + $(CC) $(TESTS) $(LIBTEST) $(LIBNAME) -o $(TEST) #This rule installs the library and the header files. This must be run #as root in order to have a high enough permission to write to the correct diff --git a/makefile.msvc b/makefile.msvc index f96e213..16d4b8d 100644 --- a/makefile.msvc +++ b/makefile.msvc @@ -1,84 +1,85 @@ #MSVC Makefile [tested with MSVC 6.00 with SP5] # #Tom St Denis -CFLAGS = /Isrc/headers/ /Ox /DWIN32 /W3 /Fo$@ +CFLAGS = /Isrc/headers/ /Itestprof/ /Ox /DWIN32 /W3 /Fo$@ default: library # leave this blank and link against libtommath if you want better link resolution MPIOBJECT=src/misc/mpi/mpi.obj -OBJECTS=src/ciphers/aes/aes_enc.obj $(MPIOBJECT) src/ciphers/aes/aes.obj \ -src/ciphers/anubis.obj src/ciphers/blowfish.obj src/ciphers/cast5.obj src/ciphers/des.obj \ -src/ciphers/khazad.obj src/ciphers/noekeon.obj src/ciphers/rc2.obj src/ciphers/rc5.obj \ -src/ciphers/rc6.obj src/ciphers/safer/safer.obj src/ciphers/safer/safer_tab.obj \ -src/ciphers/safer/saferp.obj src/ciphers/skipjack.obj src/ciphers/twofish/twofish.obj \ -src/ciphers/xtea.obj src/encauth/eax/eax_addheader.obj src/encauth/eax/eax_decrypt.obj \ -src/encauth/eax/eax_decrypt_verify_memory.obj src/encauth/eax/eax_done.obj \ -src/encauth/eax/eax_encrypt.obj src/encauth/eax/eax_encrypt_authenticate_memory.obj \ -src/encauth/eax/eax_init.obj src/encauth/eax/eax_test.obj \ -src/encauth/ocb/ocb_decrypt.obj src/encauth/ocb/ocb_decrypt_verify_memory.obj \ -src/encauth/ocb/ocb_done_decrypt.obj src/encauth/ocb/ocb_done_encrypt.obj \ -src/encauth/ocb/ocb_encrypt.obj src/encauth/ocb/ocb_encrypt_authenticate_memory.obj \ -src/encauth/ocb/ocb_init.obj src/encauth/ocb/ocb_ntz.obj \ -src/encauth/ocb/ocb_shift_xor.obj src/encauth/ocb/ocb_test.obj \ -src/encauth/ocb/s_ocb_done.obj src/hashes/chc/chc.obj src/hashes/helper/hash_file.obj \ -src/hashes/helper/hash_filehandle.obj src/hashes/helper/hash_memory.obj \ -src/hashes/helper/hash_memory_multi.obj src/hashes/md2.obj src/hashes/md4.obj \ -src/hashes/md5.obj src/hashes/rmd128.obj src/hashes/rmd160.obj src/hashes/sha1.obj \ -src/hashes/sha2/sha256.obj src/hashes/sha2/sha512.obj src/hashes/tiger.obj \ -src/hashes/whirl/whirl.obj src/mac/hmac/hmac_done.obj src/mac/hmac/hmac_file.obj \ -src/mac/hmac/hmac_init.obj src/mac/hmac/hmac_memory.obj \ -src/mac/hmac/hmac_memory_multi.obj src/mac/hmac/hmac_process.obj \ -src/mac/hmac/hmac_test.obj src/mac/omac/omac_done.obj src/mac/omac/omac_file.obj \ -src/mac/omac/omac_init.obj src/mac/omac/omac_memory.obj \ -src/mac/omac/omac_memory_multi.obj src/mac/omac/omac_process.obj \ -src/mac/omac/omac_test.obj src/mac/pmac/pmac_done.obj src/mac/pmac/pmac_file.obj \ -src/mac/pmac/pmac_init.obj src/mac/pmac/pmac_memory.obj \ -src/mac/pmac/pmac_memory_multi.obj src/mac/pmac/pmac_ntz.obj \ -src/mac/pmac/pmac_process.obj src/mac/pmac/pmac_shift_xor.obj src/mac/pmac/pmac_test.obj \ -src/misc/base64/base64_decode.obj src/misc/base64/base64_encode.obj \ -src/misc/burn_stack.obj src/misc/crypt/crypt.obj src/misc/crypt/crypt_argchk.obj \ -src/misc/crypt/crypt_cipher_descriptor.obj src/misc/crypt/crypt_cipher_is_valid.obj \ -src/misc/crypt/crypt_find_cipher.obj src/misc/crypt/crypt_find_cipher_any.obj \ -src/misc/crypt/crypt_find_cipher_id.obj src/misc/crypt/crypt_find_hash.obj \ -src/misc/crypt/crypt_find_hash_any.obj src/misc/crypt/crypt_find_hash_id.obj \ -src/misc/crypt/crypt_find_prng.obj src/misc/crypt/crypt_hash_descriptor.obj \ -src/misc/crypt/crypt_hash_is_valid.obj src/misc/crypt/crypt_prng_descriptor.obj \ -src/misc/crypt/crypt_prng_is_valid.obj src/misc/crypt/crypt_register_cipher.obj \ -src/misc/crypt/crypt_register_hash.obj src/misc/crypt/crypt_register_prng.obj \ -src/misc/crypt/crypt_unregister_cipher.obj src/misc/crypt/crypt_unregister_hash.obj \ -src/misc/crypt/crypt_unregister_prng.obj src/misc/error_to_string.obj \ -src/misc/mpi/is_prime.obj src/misc/mpi/mpi_to_ltc_error.obj src/misc/mpi/rand_prime.obj \ -src/misc/pkcs5/pkcs_5_1.obj src/misc/pkcs5/pkcs_5_2.obj src/misc/zeromem.obj \ -src/modes/cbc/cbc_decrypt.obj src/modes/cbc/cbc_encrypt.obj src/modes/cbc/cbc_getiv.obj \ -src/modes/cbc/cbc_setiv.obj src/modes/cbc/cbc_start.obj src/modes/cfb/cfb_decrypt.obj \ -src/modes/cfb/cfb_encrypt.obj src/modes/cfb/cfb_getiv.obj src/modes/cfb/cfb_setiv.obj \ -src/modes/cfb/cfb_start.obj src/modes/ctr/ctr_decrypt.obj src/modes/ctr/ctr_encrypt.obj \ +OBJECTS=src/ciphers/aes/aes_enc.obj $(MPIOBJECT) src/ciphers/aes/aes.obj src/ciphers/anubis.obj \ +src/ciphers/blowfish.obj src/ciphers/cast5.obj src/ciphers/des.obj src/ciphers/khazad.obj src/ciphers/noekeon.obj \ +src/ciphers/rc2.obj src/ciphers/rc5.obj src/ciphers/rc6.obj src/ciphers/safer/safer.obj \ +src/ciphers/safer/safer_tab.obj src/ciphers/safer/saferp.obj src/ciphers/skipjack.obj \ +src/ciphers/twofish/twofish.obj src/ciphers/xtea.obj src/encauth/ccm/ccm_memory.obj \ +src/encauth/ccm/ccm_test.obj src/encauth/eax/eax_addheader.obj src/encauth/eax/eax_decrypt.obj \ +src/encauth/eax/eax_decrypt_verify_memory.obj src/encauth/eax/eax_done.obj src/encauth/eax/eax_encrypt.obj \ +src/encauth/eax/eax_encrypt_authenticate_memory.obj src/encauth/eax/eax_init.obj \ +src/encauth/eax/eax_test.obj src/encauth/gcm/gcm_add_aad.obj src/encauth/gcm/gcm_add_iv.obj \ +src/encauth/gcm/gcm_done.obj src/encauth/gcm/gcm_gf_mult.obj src/encauth/gcm/gcm_init.obj \ +src/encauth/gcm/gcm_memory.obj src/encauth/gcm/gcm_process.obj src/encauth/gcm/gcm_reset.obj \ +src/encauth/gcm/gcm_test.obj src/encauth/ocb/ocb_decrypt.obj src/encauth/ocb/ocb_decrypt_verify_memory.obj \ +src/encauth/ocb/ocb_done_decrypt.obj src/encauth/ocb/ocb_done_encrypt.obj src/encauth/ocb/ocb_encrypt.obj \ +src/encauth/ocb/ocb_encrypt_authenticate_memory.obj src/encauth/ocb/ocb_init.obj src/encauth/ocb/ocb_ntz.obj \ +src/encauth/ocb/ocb_shift_xor.obj src/encauth/ocb/ocb_test.obj src/encauth/ocb/s_ocb_done.obj \ +src/hashes/chc/chc.obj src/hashes/helper/hash_file.obj src/hashes/helper/hash_filehandle.obj \ +src/hashes/helper/hash_memory.obj src/hashes/helper/hash_memory_multi.obj src/hashes/md2.obj src/hashes/md4.obj \ +src/hashes/md5.obj src/hashes/rmd128.obj src/hashes/rmd160.obj src/hashes/sha1.obj src/hashes/sha2/sha256.obj \ +src/hashes/sha2/sha512.obj src/hashes/tiger.obj src/hashes/whirl/whirl.obj src/mac/hmac/hmac_done.obj \ +src/mac/hmac/hmac_file.obj src/mac/hmac/hmac_init.obj src/mac/hmac/hmac_memory.obj \ +src/mac/hmac/hmac_memory_multi.obj src/mac/hmac/hmac_process.obj src/mac/hmac/hmac_test.obj \ +src/mac/omac/omac_done.obj src/mac/omac/omac_file.obj src/mac/omac/omac_init.obj src/mac/omac/omac_memory.obj \ +src/mac/omac/omac_memory_multi.obj src/mac/omac/omac_process.obj src/mac/omac/omac_test.obj \ +src/mac/pelican/pelican.obj src/mac/pelican/pelican_memory.obj src/mac/pelican/pelican_test.obj \ +src/mac/pmac/pmac_done.obj src/mac/pmac/pmac_file.obj src/mac/pmac/pmac_init.obj src/mac/pmac/pmac_memory.obj \ +src/mac/pmac/pmac_memory_multi.obj src/mac/pmac/pmac_ntz.obj src/mac/pmac/pmac_process.obj \ +src/mac/pmac/pmac_shift_xor.obj src/mac/pmac/pmac_test.obj src/misc/base64/base64_decode.obj \ +src/misc/base64/base64_encode.obj src/misc/burn_stack.obj src/misc/crypt/crypt.obj \ +src/misc/crypt/crypt_argchk.obj src/misc/crypt/crypt_cipher_descriptor.obj \ +src/misc/crypt/crypt_cipher_is_valid.obj src/misc/crypt/crypt_find_cipher.obj \ +src/misc/crypt/crypt_find_cipher_any.obj src/misc/crypt/crypt_find_cipher_id.obj \ +src/misc/crypt/crypt_find_hash.obj src/misc/crypt/crypt_find_hash_any.obj \ +src/misc/crypt/crypt_find_hash_id.obj src/misc/crypt/crypt_find_prng.obj \ +src/misc/crypt/crypt_hash_descriptor.obj src/misc/crypt/crypt_hash_is_valid.obj \ +src/misc/crypt/crypt_prng_descriptor.obj src/misc/crypt/crypt_prng_is_valid.obj \ +src/misc/crypt/crypt_register_cipher.obj src/misc/crypt/crypt_register_hash.obj \ +src/misc/crypt/crypt_register_prng.obj src/misc/crypt/crypt_unregister_cipher.obj \ +src/misc/crypt/crypt_unregister_hash.obj src/misc/crypt/crypt_unregister_prng.obj \ +src/misc/error_to_string.obj src/misc/mpi/is_prime.obj src/misc/mpi/mpi_to_ltc_error.obj \ +src/misc/mpi/rand_prime.obj src/misc/pkcs5/pkcs_5_1.obj src/misc/pkcs5/pkcs_5_2.obj src/misc/zeromem.obj \ +src/modes/cbc/cbc_decrypt.obj src/modes/cbc/cbc_done.obj src/modes/cbc/cbc_encrypt.obj \ +src/modes/cbc/cbc_getiv.obj src/modes/cbc/cbc_setiv.obj src/modes/cbc/cbc_start.obj \ +src/modes/cfb/cfb_decrypt.obj src/modes/cfb/cfb_done.obj src/modes/cfb/cfb_encrypt.obj \ +src/modes/cfb/cfb_getiv.obj src/modes/cfb/cfb_setiv.obj src/modes/cfb/cfb_start.obj \ +src/modes/ctr/ctr_decrypt.obj src/modes/ctr/ctr_done.obj src/modes/ctr/ctr_encrypt.obj \ src/modes/ctr/ctr_getiv.obj src/modes/ctr/ctr_setiv.obj src/modes/ctr/ctr_start.obj \ -src/modes/ecb/ecb_decrypt.obj src/modes/ecb/ecb_encrypt.obj src/modes/ecb/ecb_start.obj \ -src/modes/ofb/ofb_decrypt.obj src/modes/ofb/ofb_encrypt.obj src/modes/ofb/ofb_getiv.obj \ -src/modes/ofb/ofb_setiv.obj src/modes/ofb/ofb_start.obj \ -src/pk/asn1/der/der_decode_integer.obj src/pk/asn1/der/der_encode_integer.obj \ +src/modes/ecb/ecb_decrypt.obj src/modes/ecb/ecb_done.obj src/modes/ecb/ecb_encrypt.obj \ +src/modes/ecb/ecb_start.obj src/modes/ofb/ofb_decrypt.obj src/modes/ofb/ofb_done.obj \ +src/modes/ofb/ofb_encrypt.obj src/modes/ofb/ofb_getiv.obj src/modes/ofb/ofb_setiv.obj \ +src/modes/ofb/ofb_start.obj src/pk/asn1/der/der_decode_integer.obj src/pk/asn1/der/der_encode_integer.obj \ src/pk/asn1/der/der_get_multi_integer.obj src/pk/asn1/der/der_length_integer.obj \ -src/pk/asn1/der/der_put_multi_integer.obj src/pk/dh/dh.obj src/pk/dsa/dsa_export.obj \ -src/pk/dsa/dsa_free.obj src/pk/dsa/dsa_import.obj src/pk/dsa/dsa_make_key.obj \ -src/pk/dsa/dsa_sign_hash.obj src/pk/dsa/dsa_verify_hash.obj \ -src/pk/dsa/dsa_verify_key.obj src/pk/ecc/ecc.obj src/pk/packet_store_header.obj \ -src/pk/packet_valid_header.obj src/pk/pkcs1/pkcs_1_i2osp.obj \ -src/pk/pkcs1/pkcs_1_mgf1.obj src/pk/pkcs1/pkcs_1_oaep_decode.obj \ -src/pk/pkcs1/pkcs_1_oaep_encode.obj src/pk/pkcs1/pkcs_1_os2ip.obj \ -src/pk/pkcs1/pkcs_1_pss_decode.obj src/pk/pkcs1/pkcs_1_pss_encode.obj \ -src/pk/pkcs1/pkcs_1_v15_es_decode.obj src/pk/pkcs1/pkcs_1_v15_es_encode.obj \ -src/pk/pkcs1/pkcs_1_v15_sa_decode.obj src/pk/pkcs1/pkcs_1_v15_sa_encode.obj \ -src/pk/rsa/rsa_decrypt_key.obj src/pk/rsa/rsa_encrypt_key.obj src/pk/rsa/rsa_export.obj \ -src/pk/rsa/rsa_exptmod.obj src/pk/rsa/rsa_free.obj src/pk/rsa/rsa_import.obj \ -src/pk/rsa/rsa_make_key.obj src/pk/rsa/rsa_sign_hash.obj \ -src/pk/rsa/rsa_v15_decrypt_key.obj src/pk/rsa/rsa_v15_encrypt_key.obj \ -src/pk/rsa/rsa_v15_sign_hash.obj src/pk/rsa/rsa_v15_verify_hash.obj \ -src/pk/rsa/rsa_verify_hash.obj src/prngs/fortuna.obj src/prngs/rc4.obj \ -src/prngs/rng_get_bytes.obj src/prngs/rng_make_prng.obj src/prngs/sober128.obj \ -src/prngs/sprng.obj src/prngs/yarrow.obj +src/pk/asn1/der/der_put_multi_integer.obj src/pk/dh/dh.obj src/pk/dsa/dsa_export.obj src/pk/dsa/dsa_free.obj \ +src/pk/dsa/dsa_import.obj src/pk/dsa/dsa_make_key.obj src/pk/dsa/dsa_sign_hash.obj \ +src/pk/dsa/dsa_verify_hash.obj src/pk/dsa/dsa_verify_key.obj src/pk/ecc/ecc.obj src/pk/packet_store_header.obj \ +src/pk/packet_valid_header.obj src/pk/pkcs1/pkcs_1_i2osp.obj src/pk/pkcs1/pkcs_1_mgf1.obj \ +src/pk/pkcs1/pkcs_1_oaep_decode.obj src/pk/pkcs1/pkcs_1_oaep_encode.obj src/pk/pkcs1/pkcs_1_os2ip.obj \ +src/pk/pkcs1/pkcs_1_pss_decode.obj src/pk/pkcs1/pkcs_1_pss_encode.obj src/pk/pkcs1/pkcs_1_v15_es_decode.obj \ +src/pk/pkcs1/pkcs_1_v15_es_encode.obj src/pk/pkcs1/pkcs_1_v15_sa_decode.obj \ +src/pk/pkcs1/pkcs_1_v15_sa_encode.obj src/pk/rsa/rsa_decrypt_key.obj src/pk/rsa/rsa_encrypt_key.obj \ +src/pk/rsa/rsa_export.obj src/pk/rsa/rsa_exptmod.obj src/pk/rsa/rsa_free.obj src/pk/rsa/rsa_import.obj \ +src/pk/rsa/rsa_make_key.obj src/pk/rsa/rsa_sign_hash.obj src/pk/rsa/rsa_v15_decrypt_key.obj \ +src/pk/rsa/rsa_v15_encrypt_key.obj src/pk/rsa/rsa_v15_sign_hash.obj src/pk/rsa/rsa_v15_verify_hash.obj \ +src/pk/rsa/rsa_verify_hash.obj src/prngs/fortuna.obj src/prngs/rc4.obj src/prngs/rng_get_bytes.obj \ +src/prngs/rng_make_prng.obj src/prngs/sober128.obj src/prngs/sprng.obj src/prngs/yarrow.obj + +HEADERS=src/headers/tommath_superclass.h src/headers/tomcrypt_cfg.h \ +src/headers/tomcrypt_mac.h src/headers/tomcrypt_macros.h \ +src/headers/tomcrypt_custom.h src/headers/tomcrypt_argchk.h \ +src/headers/tomcrypt_cipher.h src/headers/tomcrypt_pk.h \ +src/headers/tommath_class.h src/headers/ltc_tommath.h src/headers/tomcrypt_hash.h \ +src/headers/tomcrypt_misc.h src/headers/tomcrypt.h src/headers/tomcrypt_pkcs.h \ +src/headers/tomcrypt_prng.h testprof/tomcrypt_test.h #ciphers come in two flavours... enc+dec and enc src/ciphers/aes/aes_enc.obj: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c @@ -86,12 +87,18 @@ src/ciphers/aes/aes_enc.obj: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c library: $(OBJECTS) lib /out:tomcrypt.lib $(OBJECTS) + cd testprof + nmake -f makefile.msvc + cd .. -x86_prof: demos/x86_prof.c library - cl $(CFLAGS) demos/x86_prof.c tomcrypt.lib advapi32.lib - tv_gen: demos/tv_gen.c library cl $(CFLAGS) demos/tv_gen.c tomcrypt.lib advapi32.lib hashsum: demos/hashsum.c library cl $(CFLAGS) demos/hashsum.c tomcrypt.lib advapi32.lib + +test: demos/test.c library + cl $(CFLAGS) demos/test.c testprof/tomcrypt_prof.lib tomcrypt.lib advapi32.lib + +timing: demos/timing.c library + cl $(CFLAGS) demos/timing.c testprof/tomcrypt_prof.lib tomcrypt.lib advapi32.lib diff --git a/makefile.shared b/makefile.shared index be818d7..2c5c4b3 100644 --- a/makefile.shared +++ b/makefile.shared @@ -6,10 +6,10 @@ # Tom St Denis # The version -VERSION=0:100 +VERSION=0:101 # Compiler and Linker Names -CC=libtool --silent --mode=compile gcc +CC=libtool --mode=compile gcc # Compilation flags. Note the += does not write over the user's CFLAGS! CFLAGS += -c -I./src/headers/ -Wall -Wsign-compare -W -Wshadow @@ -35,12 +35,16 @@ CFLAGS += -fomit-frame-pointer #CFLAGS += -DLTC_NO_ROLC #Output filenames for various targets. +LIBTEST=libtomcrypt_prof.la LIBNAME=libtomcrypt.la HASH=hashsum CRYPT=encrypt SMALL=small PROF=x86_prof TV=tv_gen +TEST=test +TIMING=timing + #LIBPATH-The directory for libtomcrypt to be installed to. #INCPATH-The directory to install the header files for libtomcrypt. @@ -52,7 +56,7 @@ DATAPATH=/usr/share/doc/libtomcrypt/pdf #Who do we install as? USER=root -GROUP=root +GROUP=wheel #List of objects to compile. @@ -62,90 +66,86 @@ MPIOBJECT=src/misc/mpi/mpi.o #If you don't want mpi.o then add this #MPISHARED=$(LIBPATH)/libtommath.la -OBJECTS=src/ciphers/aes/aes_enc.o $(MPIOBJECT) src/ciphers/aes/aes.o \ -src/ciphers/anubis.o src/ciphers/blowfish.o src/ciphers/cast5.o src/ciphers/des.o \ -src/ciphers/khazad.o src/ciphers/noekeon.o src/ciphers/rc2.o src/ciphers/rc5.o \ -src/ciphers/rc6.o src/ciphers/safer/safer.o src/ciphers/safer/safer_tab.o \ -src/ciphers/safer/saferp.o src/ciphers/skipjack.o src/ciphers/twofish/twofish.o \ -src/ciphers/xtea.o src/encauth/eax/eax_addheader.o src/encauth/eax/eax_decrypt.o \ -src/encauth/eax/eax_decrypt_verify_memory.o src/encauth/eax/eax_done.o \ -src/encauth/eax/eax_encrypt.o src/encauth/eax/eax_encrypt_authenticate_memory.o \ -src/encauth/eax/eax_init.o src/encauth/eax/eax_test.o \ -src/encauth/ocb/ocb_decrypt.o src/encauth/ocb/ocb_decrypt_verify_memory.o \ -src/encauth/ocb/ocb_done_decrypt.o src/encauth/ocb/ocb_done_encrypt.o \ -src/encauth/ocb/ocb_encrypt.o src/encauth/ocb/ocb_encrypt_authenticate_memory.o \ -src/encauth/ocb/ocb_init.o src/encauth/ocb/ocb_ntz.o \ -src/encauth/ocb/ocb_shift_xor.o src/encauth/ocb/ocb_test.o \ -src/encauth/ocb/s_ocb_done.o src/hashes/chc/chc.o src/hashes/helper/hash_file.o \ -src/hashes/helper/hash_filehandle.o src/hashes/helper/hash_memory.o \ -src/hashes/helper/hash_memory_multi.o src/hashes/md2.o src/hashes/md4.o \ -src/hashes/md5.o src/hashes/rmd128.o src/hashes/rmd160.o src/hashes/sha1.o \ -src/hashes/sha2/sha256.o src/hashes/sha2/sha512.o src/hashes/tiger.o \ -src/hashes/whirl/whirl.o src/mac/hmac/hmac_done.o src/mac/hmac/hmac_file.o \ -src/mac/hmac/hmac_init.o src/mac/hmac/hmac_memory.o \ -src/mac/hmac/hmac_memory_multi.o src/mac/hmac/hmac_process.o \ -src/mac/hmac/hmac_test.o src/mac/omac/omac_done.o src/mac/omac/omac_file.o \ -src/mac/omac/omac_init.o src/mac/omac/omac_memory.o \ -src/mac/omac/omac_memory_multi.o src/mac/omac/omac_process.o \ -src/mac/omac/omac_test.o src/mac/pmac/pmac_done.o src/mac/pmac/pmac_file.o \ -src/mac/pmac/pmac_init.o src/mac/pmac/pmac_memory.o \ -src/mac/pmac/pmac_memory_multi.o src/mac/pmac/pmac_ntz.o \ -src/mac/pmac/pmac_process.o src/mac/pmac/pmac_shift_xor.o src/mac/pmac/pmac_test.o \ -src/misc/base64/base64_decode.o src/misc/base64/base64_encode.o \ -src/misc/burn_stack.o src/misc/crypt/crypt.o src/misc/crypt/crypt_argchk.o \ -src/misc/crypt/crypt_cipher_descriptor.o src/misc/crypt/crypt_cipher_is_valid.o \ -src/misc/crypt/crypt_find_cipher.o src/misc/crypt/crypt_find_cipher_any.o \ -src/misc/crypt/crypt_find_cipher_id.o src/misc/crypt/crypt_find_hash.o \ -src/misc/crypt/crypt_find_hash_any.o src/misc/crypt/crypt_find_hash_id.o \ -src/misc/crypt/crypt_find_prng.o src/misc/crypt/crypt_hash_descriptor.o \ -src/misc/crypt/crypt_hash_is_valid.o src/misc/crypt/crypt_prng_descriptor.o \ -src/misc/crypt/crypt_prng_is_valid.o src/misc/crypt/crypt_register_cipher.o \ -src/misc/crypt/crypt_register_hash.o src/misc/crypt/crypt_register_prng.o \ -src/misc/crypt/crypt_unregister_cipher.o src/misc/crypt/crypt_unregister_hash.o \ -src/misc/crypt/crypt_unregister_prng.o src/misc/error_to_string.o \ -src/misc/mpi/is_prime.o src/misc/mpi/mpi_to_ltc_error.o src/misc/mpi/rand_prime.o \ -src/misc/pkcs5/pkcs_5_1.o src/misc/pkcs5/pkcs_5_2.o src/misc/zeromem.o \ -src/modes/cbc/cbc_decrypt.o src/modes/cbc/cbc_encrypt.o src/modes/cbc/cbc_getiv.o \ -src/modes/cbc/cbc_setiv.o src/modes/cbc/cbc_start.o src/modes/cfb/cfb_decrypt.o \ -src/modes/cfb/cfb_encrypt.o src/modes/cfb/cfb_getiv.o src/modes/cfb/cfb_setiv.o \ -src/modes/cfb/cfb_start.o src/modes/ctr/ctr_decrypt.o src/modes/ctr/ctr_encrypt.o \ +OBJECTS=src/ciphers/aes/aes_enc.o $(MPIOBJECT) src/ciphers/aes/aes.o src/ciphers/anubis.o \ +src/ciphers/blowfish.o src/ciphers/cast5.o src/ciphers/des.o src/ciphers/khazad.o src/ciphers/noekeon.o \ +src/ciphers/rc2.o src/ciphers/rc5.o src/ciphers/rc6.o src/ciphers/safer/safer.o \ +src/ciphers/safer/safer_tab.o src/ciphers/safer/saferp.o src/ciphers/skipjack.o \ +src/ciphers/twofish/twofish.o src/ciphers/xtea.o src/encauth/ccm/ccm_memory.o \ +src/encauth/ccm/ccm_test.o src/encauth/eax/eax_addheader.o src/encauth/eax/eax_decrypt.o \ +src/encauth/eax/eax_decrypt_verify_memory.o src/encauth/eax/eax_done.o src/encauth/eax/eax_encrypt.o \ +src/encauth/eax/eax_encrypt_authenticate_memory.o src/encauth/eax/eax_init.o \ +src/encauth/eax/eax_test.o src/encauth/gcm/gcm_add_aad.o src/encauth/gcm/gcm_add_iv.o \ +src/encauth/gcm/gcm_done.o src/encauth/gcm/gcm_gf_mult.o src/encauth/gcm/gcm_init.o \ +src/encauth/gcm/gcm_memory.o src/encauth/gcm/gcm_process.o src/encauth/gcm/gcm_reset.o \ +src/encauth/gcm/gcm_test.o src/encauth/ocb/ocb_decrypt.o src/encauth/ocb/ocb_decrypt_verify_memory.o \ +src/encauth/ocb/ocb_done_decrypt.o src/encauth/ocb/ocb_done_encrypt.o src/encauth/ocb/ocb_encrypt.o \ +src/encauth/ocb/ocb_encrypt_authenticate_memory.o src/encauth/ocb/ocb_init.o src/encauth/ocb/ocb_ntz.o \ +src/encauth/ocb/ocb_shift_xor.o src/encauth/ocb/ocb_test.o src/encauth/ocb/s_ocb_done.o \ +src/hashes/chc/chc.o src/hashes/helper/hash_file.o src/hashes/helper/hash_filehandle.o \ +src/hashes/helper/hash_memory.o src/hashes/helper/hash_memory_multi.o src/hashes/md2.o src/hashes/md4.o \ +src/hashes/md5.o src/hashes/rmd128.o src/hashes/rmd160.o src/hashes/sha1.o src/hashes/sha2/sha256.o \ +src/hashes/sha2/sha512.o src/hashes/tiger.o src/hashes/whirl/whirl.o src/mac/hmac/hmac_done.o \ +src/mac/hmac/hmac_file.o src/mac/hmac/hmac_init.o src/mac/hmac/hmac_memory.o \ +src/mac/hmac/hmac_memory_multi.o src/mac/hmac/hmac_process.o src/mac/hmac/hmac_test.o \ +src/mac/omac/omac_done.o src/mac/omac/omac_file.o src/mac/omac/omac_init.o src/mac/omac/omac_memory.o \ +src/mac/omac/omac_memory_multi.o src/mac/omac/omac_process.o src/mac/omac/omac_test.o \ +src/mac/pelican/pelican.o src/mac/pelican/pelican_memory.o src/mac/pelican/pelican_test.o \ +src/mac/pmac/pmac_done.o src/mac/pmac/pmac_file.o src/mac/pmac/pmac_init.o src/mac/pmac/pmac_memory.o \ +src/mac/pmac/pmac_memory_multi.o src/mac/pmac/pmac_ntz.o src/mac/pmac/pmac_process.o \ +src/mac/pmac/pmac_shift_xor.o src/mac/pmac/pmac_test.o src/misc/base64/base64_decode.o \ +src/misc/base64/base64_encode.o src/misc/burn_stack.o src/misc/crypt/crypt.o \ +src/misc/crypt/crypt_argchk.o src/misc/crypt/crypt_cipher_descriptor.o \ +src/misc/crypt/crypt_cipher_is_valid.o src/misc/crypt/crypt_find_cipher.o \ +src/misc/crypt/crypt_find_cipher_any.o src/misc/crypt/crypt_find_cipher_id.o \ +src/misc/crypt/crypt_find_hash.o src/misc/crypt/crypt_find_hash_any.o \ +src/misc/crypt/crypt_find_hash_id.o src/misc/crypt/crypt_find_prng.o \ +src/misc/crypt/crypt_hash_descriptor.o src/misc/crypt/crypt_hash_is_valid.o \ +src/misc/crypt/crypt_prng_descriptor.o src/misc/crypt/crypt_prng_is_valid.o \ +src/misc/crypt/crypt_register_cipher.o src/misc/crypt/crypt_register_hash.o \ +src/misc/crypt/crypt_register_prng.o src/misc/crypt/crypt_unregister_cipher.o \ +src/misc/crypt/crypt_unregister_hash.o src/misc/crypt/crypt_unregister_prng.o \ +src/misc/error_to_string.o src/misc/mpi/is_prime.o src/misc/mpi/mpi_to_ltc_error.o \ +src/misc/mpi/rand_prime.o src/misc/pkcs5/pkcs_5_1.o src/misc/pkcs5/pkcs_5_2.o src/misc/zeromem.o \ +src/modes/cbc/cbc_decrypt.o src/modes/cbc/cbc_done.o src/modes/cbc/cbc_encrypt.o \ +src/modes/cbc/cbc_getiv.o src/modes/cbc/cbc_setiv.o src/modes/cbc/cbc_start.o \ +src/modes/cfb/cfb_decrypt.o src/modes/cfb/cfb_done.o src/modes/cfb/cfb_encrypt.o \ +src/modes/cfb/cfb_getiv.o src/modes/cfb/cfb_setiv.o src/modes/cfb/cfb_start.o \ +src/modes/ctr/ctr_decrypt.o src/modes/ctr/ctr_done.o src/modes/ctr/ctr_encrypt.o \ src/modes/ctr/ctr_getiv.o src/modes/ctr/ctr_setiv.o src/modes/ctr/ctr_start.o \ -src/modes/ecb/ecb_decrypt.o src/modes/ecb/ecb_encrypt.o src/modes/ecb/ecb_start.o \ -src/modes/ofb/ofb_decrypt.o src/modes/ofb/ofb_encrypt.o src/modes/ofb/ofb_getiv.o \ -src/modes/ofb/ofb_setiv.o src/modes/ofb/ofb_start.o \ -src/pk/asn1/der/der_decode_integer.o src/pk/asn1/der/der_encode_integer.o \ +src/modes/ecb/ecb_decrypt.o src/modes/ecb/ecb_done.o src/modes/ecb/ecb_encrypt.o \ +src/modes/ecb/ecb_start.o src/modes/ofb/ofb_decrypt.o src/modes/ofb/ofb_done.o \ +src/modes/ofb/ofb_encrypt.o src/modes/ofb/ofb_getiv.o src/modes/ofb/ofb_setiv.o \ +src/modes/ofb/ofb_start.o src/pk/asn1/der/der_decode_integer.o src/pk/asn1/der/der_encode_integer.o \ src/pk/asn1/der/der_get_multi_integer.o src/pk/asn1/der/der_length_integer.o \ -src/pk/asn1/der/der_put_multi_integer.o src/pk/dh/dh.o src/pk/dsa/dsa_export.o \ -src/pk/dsa/dsa_free.o src/pk/dsa/dsa_import.o src/pk/dsa/dsa_make_key.o \ -src/pk/dsa/dsa_sign_hash.o src/pk/dsa/dsa_verify_hash.o \ -src/pk/dsa/dsa_verify_key.o src/pk/ecc/ecc.o src/pk/packet_store_header.o \ -src/pk/packet_valid_header.o src/pk/pkcs1/pkcs_1_i2osp.o \ -src/pk/pkcs1/pkcs_1_mgf1.o src/pk/pkcs1/pkcs_1_oaep_decode.o \ -src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o \ -src/pk/pkcs1/pkcs_1_pss_decode.o src/pk/pkcs1/pkcs_1_pss_encode.o \ -src/pk/pkcs1/pkcs_1_v15_es_decode.o src/pk/pkcs1/pkcs_1_v15_es_encode.o \ -src/pk/pkcs1/pkcs_1_v15_sa_decode.o src/pk/pkcs1/pkcs_1_v15_sa_encode.o \ -src/pk/rsa/rsa_decrypt_key.o src/pk/rsa/rsa_encrypt_key.o src/pk/rsa/rsa_export.o \ -src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o src/pk/rsa/rsa_import.o \ -src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_sign_hash.o \ -src/pk/rsa/rsa_v15_decrypt_key.o src/pk/rsa/rsa_v15_encrypt_key.o \ -src/pk/rsa/rsa_v15_sign_hash.o src/pk/rsa/rsa_v15_verify_hash.o \ -src/pk/rsa/rsa_verify_hash.o src/prngs/fortuna.o src/prngs/rc4.o \ -src/prngs/rng_get_bytes.o src/prngs/rng_make_prng.o src/prngs/sober128.o \ -src/prngs/sprng.o src/prngs/yarrow.o +src/pk/asn1/der/der_put_multi_integer.o src/pk/dh/dh.o src/pk/dsa/dsa_export.o src/pk/dsa/dsa_free.o \ +src/pk/dsa/dsa_import.o src/pk/dsa/dsa_make_key.o src/pk/dsa/dsa_sign_hash.o \ +src/pk/dsa/dsa_verify_hash.o src/pk/dsa/dsa_verify_key.o src/pk/ecc/ecc.o src/pk/packet_store_header.o \ +src/pk/packet_valid_header.o src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o \ +src/pk/pkcs1/pkcs_1_oaep_decode.o src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o \ +src/pk/pkcs1/pkcs_1_pss_decode.o src/pk/pkcs1/pkcs_1_pss_encode.o src/pk/pkcs1/pkcs_1_v15_es_decode.o \ +src/pk/pkcs1/pkcs_1_v15_es_encode.o src/pk/pkcs1/pkcs_1_v15_sa_decode.o \ +src/pk/pkcs1/pkcs_1_v15_sa_encode.o src/pk/rsa/rsa_decrypt_key.o src/pk/rsa/rsa_encrypt_key.o \ +src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o src/pk/rsa/rsa_import.o \ +src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_sign_hash.o src/pk/rsa/rsa_v15_decrypt_key.o \ +src/pk/rsa/rsa_v15_encrypt_key.o src/pk/rsa/rsa_v15_sign_hash.o src/pk/rsa/rsa_v15_verify_hash.o \ +src/pk/rsa/rsa_verify_hash.o src/prngs/fortuna.o src/prngs/rc4.o src/prngs/rng_get_bytes.o \ +src/prngs/rng_make_prng.o src/prngs/sober128.o src/prngs/sprng.o src/prngs/yarrow.o + +HEADERS=src/headers/tommath_superclass.h src/headers/tomcrypt_cfg.h \ +src/headers/tomcrypt_mac.h src/headers/tomcrypt_macros.h \ +src/headers/tomcrypt_custom.h src/headers/tomcrypt_argchk.h \ +src/headers/tomcrypt_cipher.h src/headers/tomcrypt_pk.h \ +src/headers/tommath_class.h src/headers/ltc_tommath.h src/headers/tomcrypt_hash.h \ +src/headers/tomcrypt_misc.h src/headers/tomcrypt.h src/headers/tomcrypt_pkcs.h \ +src/headers/tomcrypt_prng.h testprof/tomcrypt_test.h 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 - -#Header files used by libtomcrypt. -HEADERS=src/headers/ltc_tommath.h src/headers/tomcrypt_cfg.h \ -src/headers/tomcrypt_misc.h src/headers/tomcrypt_prng.h src/headers/tomcrypt_cipher.h src/headers/tomcrypt_hash.h \ -src/headers/tomcrypt_macros.h src/headers/tomcrypt_pk.h src/headers/tomcrypt.h src/headers/tomcrypt_argchk.h \ -src/headers/tomcrypt_custom.h src/headers/tomcrypt_pkcs.h src/headers/tommath_class.h src/headers/tommath_superclass.h +TESTS=demos/test.o +TIMINGS=demos/timing.o #The default rule for make builds the libtomcrypt library. default:library @@ -164,11 +164,14 @@ src/hashes/sha2/sha512.o: src/hashes/sha2/sha512.c src/hashes/sha2/sha384.c src/hashes/sha2/sha256.o: src/hashes/sha2/sha256.c src/hashes/sha2/sha224.c #This rule makes the libtomcrypt library. -library: $(LIBNAME) +library: $(LIBTEST) $(LIBNAME) + +$(LIBTEST): + cd testprof ; CFLAGS="$(CFLAGS)" GROUP=$(GROUP) USER=$(USER) VERSION=$(VERSION) LIBPATH=$(LIBPATH) LIBNAME=$(LIBTEST) make -f makefile.shared $(LIBNAME): $(OBJECTS) - libtool --silent --mode=link gcc $(CFLAGS) `find . -type f | grep "[.]lo" | xargs` -o libtomcrypt.la -rpath $(LIBPATH) -version-info $(VERSION) - libtool --silent --mode=link gcc $(CFLAGS) `find . -type f | grep "[.]o" | xargs` -o libtomcrypt.a + libtool --silent --mode=link gcc $(CFLAGS) `find . -type f | grep "[.]lo" | grep "src/" | xargs` -o libtomcrypt.la -rpath $(LIBPATH) -version-info $(VERSION) + libtool --silent --mode=link gcc $(CFLAGS) `find . -type f | grep "[.]o" | grep "src/" | xargs` -o libtomcrypt.a ranlib libtomcrypt.a libtool --silent --mode=install install -c libtomcrypt.la $(LIBPATH)/libtomcrypt.la install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(INCPATH) @@ -177,17 +180,19 @@ $(LIBNAME): $(OBJECTS) #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) + gcc -o hashsum hashsum.o -ltomcrypt_prof -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) + gcc -o crypt encrypt.o -ltomcrypt_prof -ltomcrypt $(MPISHARED) 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) + gcc -o tv_gen $(TVS) -ltomcrypt_prof -ltomcrypt $(MPISHARED) + +test: library $(TESTS) + gcc -o $(TEST) $(TESTS) -ltomcrypt_prof -ltomcrypt $(MPISHARED) + +timing: library $(TIMINGS) + gcc -o $(TIMING) $(TIMINGS) -ltomcrypt_prof -ltomcrypt $(MPISHARED) + diff --git a/notes/ccm_tv.txt b/notes/ccm_tv.txt new file mode 100644 index 0000000..3ff4b77 --- /dev/null +++ b/notes/ccm_tv.txt @@ -0,0 +1,214 @@ +CCM Test Vectors. Uses the 00010203...NN-1 pattern for nonce/header/plaintext/key. The outputs +are of the form ciphertext,tag for a given NN. The key for step N>1 is the tag of the previous +step repeated sufficiently. The nonce is fixed throughout at 13 bytes 000102... + +CCM-aes (16 byte key) + 0: , 54C92FE45510D6B3B0D46EAC2FEE8E63 + 1: DA, 7A8984228DCF944903936CA9D7709ACF + 2: B95E, 1056DE0CBBEEA760ED2053FFEB554EA6 + 3: 58FF3B, A42DE1A812D29BBC6C1C5AC808565437 + 4: 9D6E6FB6, 5E8E0422792999381ED669CE17601D34 + 5: 40D49E851D, B076B4ED79BF0155B39A743550593944 + 6: 015356B9A6E1, 8D62CEFC451CAE4A21C1C579C6CAA128 + 7: A2CF0A77AE0DE2, 97B9D201740FA59E863513EDACC59FFB + 8: A44C68E52F95B48B, A461B79D4D9B8ADF6C6618E6ECDC059A + 9: F56B8AD68AA31F22B9, C5C7D2E6FE34D94CE72B86DA55679080 + 10: 5C17EEBF4E348CBE3278, 29FAE7B470CB652C501343FE23B25894 + 11: 1EE960BFAE360302D834E3, 8F8F475EB9BAB29CE14A9CF42C30B148 + 12: EFF6BA1F2B1389237C6C045E, C895302DD8E75096951EF5CA63BFDD67 + 13: 5A1179A4047334CCD9162F36EB, 110987D37F45422625DEA402BD7580EB + 14: F26E2C27E7D287B182FA42879978, 530FDE90C13A01EBCA86449073A3B035 + 15: 77BFE79B4BC87116EC5232606E890F, 280994EB0E16C7CF10F31BB60DBF52C8 + 16: 9926A4CE1AD70B89CC0050A58B958742, A635B4272EBFA1F83DAE270452D877E7 + 17: BAAF99CAE4753E3304D6F8F9C0CD366C68, A6F606AACD0B87923B43C3EB61AC3965 + 18: F72453C6765352A31494FA02B388E407B1FB, 0A446D28B7C5845C3621B4D3A0FA98DB + 19: A7372589A86B2E137F124A96618095EB5E1435, 3C59A6A858947FEBFD32441E37309F1A + 20: 5683E13A4E82A1AB8B3DC2051B6DBF2E1F2BB417, 459D1B0D2CF2C30B5ED5C237D07DFC19 + 21: 33594C4B84536C23DA5AB2117E9267258CCE5DEC3B, 6E4BB70A72343E142AC4E31CE0FE6A77 + 22: 332EDC9A3BDB90DBCCF317AC55BE5855CA9BCA2A73C4, 9FB310E5FFF5C754EE1E5FFF865F1656 + 23: 734618677055469335FFD574B008F2C68B78633F79010E, FAD31386E42BB4EA76A643A9004A8CB4 + 24: BA6F6ABA2AF35895F7F966D71F4E91A0BDD1DD551826F861, 25A3EC1C91C26283BAA5975390285AB2 + 25: FF519213E858E36AC8D92450F81CA46C8CA8AB129A997EBB36, 0D4AB2B7A5EB02242C01A81CEBF5D84E + 26: B1F80058C3B4316EA86E9A898CD0B9C0366DFCB2AEC0799312D5, 0F4FF2759EDDF6349F4E23F284FAAD2E + 27: 00BDC15012F8183112D5C3A135DC60DC9C764A04BD39A8E041F1D9, 0C68BC9E6A6BF1B01743F3183C9B7C80 + 28: 3022FD12969D925365C553D98D59E5D1EC494540909D1FA794F41E18, 05E61844943E78DB9BD417DDDE9C98B2 + 29: 4F4A4554BFED6BAA09E3D8843C4EA3807B8762799C1D21289A46575389, 3A59A6DC9230020FE061466A92BBCAFD + 30: 6AE735EB15D9B39C8AD0E54F45307AAD97DB9F8A2A66BDC9BABCCFBD54A3, 0BDB365E493A9E160EEFD7DE24101870 + 31: 4AF19F00EAE55FED2304B94FBCA29383042F2BE711041323C1D9F14BA63383, 94561581E496553D068052BA698683D2 + 32: C2438BC46A92A465E0DB41E638CC6C8E0029C4DA842CA4140D73F90985EABA9C, 0F5A69F52AA8D8508D09E642511E54E5 + +CCM-rc6 (16 byte key) + 0: , D01FACF2BB577BFA6194800E53FB4A00 + 1: 65, 92E48F7300FA2697E9E0FF80DD187237 + 2: AF5C, 332863BC515649D5BCAB6A2FE5F5250D + 3: E7C89D, 49A641F027C65A15100009D99E79CF3F + 4: ACB36D46, 53DE328A8B4B14CAD363BED53DACE8A1 + 5: C3ADAE6CCF, F713F5079BD77046F95D8685CDF522DC + 6: 5A8CABC912DA, FB97B059D2BE1273497FA8D2739A1505 + 7: 27F101DD6D0894, 266ACEF34476A0E64410D209219335D0 + 8: 66164DA09BE2F46D, EFC64C01890A5B562AF39ADFC48E1CA9 + 9: 1B0018895394753995, FA894E1C882D96E35A4C238708931F3D + 10: D346062826187BAEFC3B, A036AE1D3C02E2AD23541DE095AC7B84 + 11: EFB375BA1138339FA1B504, CDD4232FF4664D59D5AC6BE32CBE1B35 + 12: AFCF494078D7D7E6D9803FD5, 07E06ED923F76150BE82C1DDCB62C4DD + 13: 75DF2EC91379408DA426A444E4, 440ACDF2A6567FA3A5009DDFE502A1A1 + 14: 3B36B62B01E324E702694305DD29, 4093598607DCD9993845D1837D211FE2 + 15: 7DF6595C9711B164C99CB246B4D57E, F364993B2C187058F466B62D11E0F94D + 16: D317EE9EE1746D1B89A4CC52D88F0819, 41856B0B229D38344FA718E04CA57A8B + 17: 85252277A97CA7553007995BD5A0DCD372, BDEEAB636BD1ACC8D5A23F658150FA30 + 18: 36FF305AC6EF662C155A1C15A6C195D3EC88, 9AC48EF07A510E308E06E79C0C80C3A0 + 19: 51645A614313E978F6DCE7BBDDEDC33E3284AB, E9F7723E763AD50161C0671C4034FD0A + 20: 3CB9E6D0730FE05F903D338708AD8E34BFBB3285, 8A12185DAD518049F0FAC945A8FB305A + 21: 276E37D246C40ABF32DC83007B95390EE801CDA6E3, 73FA1D310D031E0A0A3A1421661B4697 + 22: 4444BB070EDFBD1AC59D0BF70D66F48F0830069F3562, 9DCB6A99CBCCE3C8AEF29F06AF5057FB + 23: D16BA084CF82EDD2E43349311140BF3A2E37DE40544BF3, CB93C5AD60C700D4EA653136101AACCC + 24: 3FBAEBB36E2B74014043BA7D72F899B0D8DED883F592D778, 54DEA31D7EEA863A06A16D6C9B25DC13 + 25: 3614B5428B790793F31E23670A38A070B65DB8E51C61FEA9C9, A91B750FD7ABFF18376C982DFA0C8872 + 26: AC15FD90A4C254BA1406BE7DBA5694BB2625F634C69F45CCCD04, E6F97BCC8526BE3C04BA139EB50E65DF + 27: B506E83557E48553BD8557411D2C17D64005E734BA5A5FF1CF98B1, 6FA001758A19F783A71C97AF1AA61F94 + 28: F07721663400838947EA1B9404D9683556F2D911429A9F59E3F5AD31, 376A1165A30C919E96C3706A4AB5DB37 + 29: 98B5EB8FE0005E515A585D8F44D838FA590054EA5201CD444366B6F71E, D8C58448F601F2C05F24ED2CC349C78B + 30: E36E2FC225767CC1E2C388BEBC2C81C340FEF5B504575D5FA49682E1C214, CFED56F38CA4F84E6E1E16CEF50A6154 + 31: 7A9FDD8E481B822B3D282AAF726944101ED61DAE73782DE055D7D305E36B27, 328B10841E977041CBD13C39CD70F03F + 32: 48AE8B5FA027930A7BCEC27468D795D0D8E6099C5F0558361B3AD20C1ECFF89F, B180AA9353E9EB6A22710A4DE872FACB + +CCM-safer+ (16 byte key) + 0: , E106F41D61402E532662213EBA471BFF + 1: 05, 1749600C7045647DCB3293C0724E7A21 + 2: 2355, 80DD597665723F4AEFFF760C5C6C5EE2 + 3: 5F4CD8, 59AE54E63A8CF4DBAD050B42CE922013 + 4: 75F63A43, C31B6BD3125C036C99507DDEE0197201 + 5: 51D4D87B8D, 0F3872088CDEB0E958C35F343677AC24 + 6: 8CF6D81A274C, C8E688954E72A052B5F8D1CA46FB44B0 + 7: 5EB8283B299AB1, 5977CB96C8D439DE3A86AE0452A2EE34 + 8: 829B1A4EA8643EAA, 1E892D3DFB73A469035CA81DD7F937D1 + 9: 0FEEF9504CF0F4E282, EDCBED7C61E8E2D24392B4145218F0AB + 10: DEF7679D3073D461A94C, D7ABAE561901CBB30FD7D9467C088B3B + 11: 625FD679C7354A74D62893, 450E3954857640DDF4C7A95A6E202A1E + 12: 3C9E76E4E2D4D95FEABD5C90, CD4467F695B7ED8973AEED5A822B347A + 13: B1B6294ECEAE6AEE4853731CA9, 6042302DAE598822BE8554BE038119CF + 14: 204BF480582D4BA408BAD23CEB52, 4D6B87334E1BFB9BA2D42B89B24165B2 + 15: 277591770E3E2DB97A3011D9616991, 75D0A4B9937748EAE7794056F7A8A7FE + 16: 5669F75D0C908BFF7B82095231B86DAA, 3E816776A73FB89276534A3646C0F8FB + 17: 37E621EF5A043A83FC98A65329891BC031, 159A823EA61B3A47B42EFCF12F304725 + 18: 18AC6ECF3F478A0797BF813C871235A9D309, 9B415B1B3A933B22C9027E2D72764956 + 19: 671484C7587DAAB885C7F2FAF030081B452CC6, 574A63D113A5ECEC877D5A368A3160AA + 20: D7AB0F7D46B7ED976C8F6E7D0C6AABE3CAAA5A6E, 266C7A025C4EDF657DD42EB82BB6616A + 21: D60E4CFC6500E237276A69F35AE4BBAE17371392EF, 6ED2A1673F8B4DB795547D9D93D76D8B + 22: FAC6E21979D8D9896C790CB883C29F84D6820AE4FD4B, 1C7B6D73200E3C2DC5C701152F38EE8E + 23: 39240DC2B544CA8BEBBB4EA499FD48A5EE707198AE8AC8, E7FFD169552665ADE7B9C0DFFDD04EBD + 24: 6BE2C24172CAA192D55CC3E640E34675DD7F441CE5DB0FC0, 760CA976355281F76E49A2856A4EC7A0 + 25: 0E20427218D6447D6E23FA4832CB8D2A172B23FDC542B41524, 27D0F37E109252FF5E6F6F703CA784F5 + 26: 0AF75BD89028A5691B8B7993B9CE4FD24334A312DE28212C8B2C, AFE4C6B193B0F1796FC9E6C23292C060 + 27: 6830D8E2E6DEC1476796DA44C982D36409E268F966283A66E801ED, 9E2C92D5B30EB0943E17869ED4C789EC + 28: 75ED280BEECD7768F7E032071F0E06D9D6BF1C9FF8E5DEB536DCD4BA, BF0DD11D633DBA5DCD25F4172765570B + 29: DF1FAECC1DB24718236B18B90B354F405FD5DE1257EC43F811F4A43DCD, 48D182E572E794350BBDA91FD76B86BC + 30: 176681E38ACACCD3C625F554C1F7A2D7C2C474C9444EAC8929B8C36EC05E, 080E109FFC5D247F1007217DD642BBA3 + 31: 8A8172C21D88A1FDD43089C545C308507617F7BDB02C47CF2719F1484407E2, 1A0D10B0AF5BE21BF19D570D3FDA5BCE + 32: 0A93CAE2B95517773A4009FD3438231A207B9D46AABAE83FC4E1057EA4E2D6B4, 717AEF2F55DC8669F7E2D0298F8A7BE9 + +CCM-twofish (16 byte key) + 0: , 33B3DF1B59C84DD3C15E4FEB66173303 + 1: BF, 92DCEBF1C11DD0B028DEC944A555E4C6 + 2: 8A4F, A859C7F76291326D821BB3C7519657C0 + 3: BAE755, 14D7C2EFBCA1063460FEFCEBAE3AD79A + 4: 25695BC6, 9358BC434B14B59ED17F9C0D3F51DCB1 + 5: 1D9FC70ECE, 2A86578FA3A8C702E2E6723DB9A9893F + 6: AC39F1DF3661, 3F9C71EE0506FD2BAFFEE7200D22CD92 + 7: D330A915EED9D0, 22DC25EDF5ACDEF8358BE2A3082112BC + 8: EF913ADAE6380507, E87D72BB6395EEEF2AD4F546B4033DE8 + 9: 5EC16994E762BCE467, D7700F7BF4FE026A2076F161C3383A0A + 10: 7EEB4910B7C2B540B490, 40C88A977E1DCDDABD749ABC9A0C60F8 + 11: E5DD32FF54D39451CC2AF8, 541B1558B5AFF6E9EFBEE496D60AD65C + 12: 242C2900F859966B6627FF5C, 1CED148098350F3A5D1B5634180817A3 + 13: EEF025B9E4EB867B127EBD19D4, AD0179A07AD1418C25F40E123C2BEF47 + 14: C5E812B0AE37098686E2C4452C12, 02FC88AAA62E34742BB8577A651E922B + 15: 7BCAB32D1A871A62F9C781AFCAC60C, 2CD1C11EE197D9E130359F76E7F49251 + 16: 1E82D8B8EED9A730D1670F0DCFF17B60, B7730261560EA6CF715FF7006D5FEFE2 + 17: 0E1966992E360DC81312B28ECA6865B811, 10C40ACD169CB0F2A6FFC99F9A5516EA + 18: 5F5418C1322BF7EB828CF27C1F72086515BE, 90F8ED0447171A10476DED39F7518075 + 19: 6C552506FA167FB8AA12E9F416930031487D4E, C992009F83F31A7BF922BFAE68C4134B + 20: 38429D966676406B17638DB7F9F7205250408BB2, 3385A50E9789D2C63835A80EFE9CFAE4 + 21: 56EF426315EF96BE4C60B49F41C9BDDE2E0CDB3C22, 2D51D5B4F5B04BEF3BC1A7CF1AEA70E9 + 22: 314B075C097EE531ECCE6AD7CEF22A72AAFCEFB02029, FB7A7D84D23FF524D060871D90FAC106 + 23: 61CCCF7E2A9B3E46CD0A94D7F4A7617BB0DBA2D989907A, B3F4D46094732F3EDD81E0755F0C52EB + 24: 7A812A3BCED4E0A72FB81218BD5A4E33D69CA18834FFAE61, 487F80588B41F4E1198124708987667D + 25: DBFAB77EF07AA4C9ED2B05500BDFA00FE3F19F15F97A74880A, 84504D9EECBC6CE11B18BD105DE55E2C + 26: E676D4739B01B5101E36BF8D9F4FAE8F767C028E83A6D5B39664, 3141A05669807BCA30F0934F599FD077 + 27: D8FEBD069D87C1EE504CB8F72ADFF2166B14BA40B17B4DAA439668, 1D99A301943041C2F7A71432DA736FE0 + 28: D98E2A1CFFAB28341F92C41971A21AD0FDDE733EA25F2607967CD0C3, 42E05A53BF4F1A6C5B7F84742ECE031B + 29: 13FA412B484945C1FE8291A7EB8F8FB78D2DC2C72C5132386EA82BF4A6, A1A8E8B026DD116B0F9C73EB14C1C7CD + 30: 10ABD2DC25C8BA594FBFA9312E69C1A2DBF326475AF2080E55E3611FBC0E, 49DF8A5171DAC3FB684BA2CF7FBB3D3B + 31: F401D2123619B81F54F307B783362CC40FB4FB2433CF51F5543A147BCD1FE5, ACBB670CB3722059B4B9FBEE67703E98 + 32: 839A9BFA1D3CA37924BC6648DED2291FC61736A3638906D9C5DA28A66AA684AC, CD07B83C8E0C3E6FB4115A149BDF6FDA + +CCM-noekeon (16 byte key) + 0: , FF73C6775C61DB36D9B5EEC812091FF7 + 1: 5F, 7D2AEA62A5202E3C4FBE05F33EBE4CC5 + 2: 0EA5, 312ED15FDDAB6EEEAC6AF9BE9CE698FA + 3: 968F95, FA1AD58B85B93B5A4B5096C881F773C3 + 4: 9A8F4069, 8911063ADDF79E27D9DCEFF3F440E6D7 + 5: A5C0376E27, 9553F44B0BA8039527F8E05CD70AD8B0 + 6: 5B097736F3DA, 405B7EC685FC94903B36AC8E700558B8 + 7: 616810AE303B2C, 64C95A2DF5263F7BE6D1F9F3CF88EADE + 8: C8D69A2E1170532C, 073A7E426266237FD73D8109F55AE5D3 + 9: 3E42CDB7DA4A72F2E0, 48675EA4302CA6BFE5992DE96CE43BB3 + 10: 88532CC1F3E321F66D64, 528B3516C6D9A4B5390DD32C2A2E6C19 + 11: 9216A8FC9A961E7F602F7D, B03047186B783844F5B6757057576B38 + 12: 89B0858D4FDE6795EDE19CCC, F4530A2DCA823307AEDE5AF34E5C4191 + 13: A676E20BB0A5E84FD0B9149BF7, 11B823B315DA93B0E15780851526D4BD + 14: 903AD5C108C43A80436FE2117EF0, EB1C79C7DF20CE2967A99783EA8D6EF8 + 15: 81774C36F46F67159B7FFC24C080D7, 2E9E4812D9A92977EC34922782B6420D + 16: 63FD1C3F692D64B2DA3982FCD474A5D4, 04171AE84857713A9BABBD4564875D33 + 17: B1BF6AD99F83C9173C6C021ACA74C5431C, 38D17D4F6AA3C24B8F3B465EAACE0A1E + 18: 0948D1ED59F07DE44A96A76E05B0B6F7C309, 1848D886FCFF35E85B0DC3CBE5BEE7FA + 19: 3458E5911222F9C555A1054C7D9748876DA39A, 584AFAE72FB6065A74BE016CF39D2E86 + 20: 641F3867185D0605E9D666AB605187E75A1299EF, 6F9332E6FB5EA0CE811E3345593CD163 + 21: 0676622D07733EF31A765AAB1E713FCE329277FB16, 88547474050FFC986930CC04BA8A03F0 + 22: 79861EC2FD2BCC5C12B69F30A1575FC66AC1405281BB, FC68EEAC8F39ED69D312AEABF8000084 + 23: CB2731835A576F7F8F2C2786D786FB6186E2F85D89DA3B, 3ED9E95BC51CF6368E6EF63667B35BD8 + 24: 3CB1C02FADB6DD5483BC5D3C03D944102CFCEDF82B913402, 1C3F60C989A6FBF41A7AF4F29115C334 + 25: E69FAEA5E3D0B76EF9E70F99C5918D934D0E9836F248DB9EEE, 7F1916B2CF7C9A5E3F5581D365ADBD31 + 26: 36779AD755A9DF2DC3C5824DC2F7DD4FFE038628A4E1A1C33AE7, 2BDED3703468D267F8AB7EC0AF8F1E65 + 27: E9D325646A41EE5AA7DABCDE98DE83440A7DC02714BA0AEE017E22, 972F4D7832F3371C60DCD04A6DEDEA15 + 28: 0FAAE3F6028A28A80BBFE71FA7AA9042E538B41A0D514D6EB4EE6029, F7B3925495E260249ACC6E1CBE956BC5 + 29: A9CC39EFFEE354C0E0579256AA85CBAA7B10E670DD3828A7A05DA0F49D, 28D9D20187AFE70AD9DD16759F0EFEB5 + 30: 032F4BBB4EBF2E65758C541FDAFF2107DDBED399739849F8EBB41AF9711F, A3436981ED637CE5EEE01B380C46ACAD + 31: 7B321ED831CE96A603668E3E74BBC7453749A03D04A1B38E95966E6CC488F0, 88D1DADF2C1EE0BA579D0A8A90C1E62A + 32: D862B0BD0E2178AE05AEFB14F34C791547C5956F1F3B5BD525926578DE383A94, BF32CFE059F27222DC55D3E7CE7C5F10 + +CCM-anubis (16 byte key) + 0: , C85F41475E06F25682F855C3D45A6523 + 1: 25, 437BD73ECB8CFFAD9B2876F08D4BDA36 + 2: 5ADC, 5C762058A5EF71278B69F567F18CBE51 + 3: 95E541, DF099E8218AEDE8087791B38298334E9 + 4: 2DAA84E4, 7437094198E4AD2647C2618248769A26 + 5: B9641C5855, 91B02EC44D22460BFF22BB40C799E20C + 6: 102012BCEFA5, E60488DA65D683182F0EFDF9DA52A78C + 7: 8F14972CA4F8EA, C26B51F20ACDEC7DCA911500CF1241ED + 8: ED2714B652972256, 8BA29459D5D370FC608EE362B55B7633 + 9: BF58A269A4F59CE0A4, D69080820F836E5B5CA8F393E61ED009 + 10: 44AF1F715ADAF26C6EF0, FEFBC7DB75ECDDBA4A13CBF9A57873D8 + 11: 77CDE1B951F0803893642D, FBF8B80B061703504D8D3A7718366B6E + 12: DE599BAAC9D3EFD9FCD47E44, F636EC35D172D661F01746FF86688B95 + 13: A792B8359050C4866572977415, AE67D4EED92E63A14003FBC936EEF43E + 14: 62D5A7A4DFB78A175831627987CB, 25F7B440DBE9902C28B28E50BF02C516 + 15: B6F289459F924C76586F4EEA0C1CAA, 54266B4424C3AF6E81F6CC4F2437F54E + 16: 884B7DF3395F063DCA26BDF9F2FEF4EA, E3C2BFA1964EFDF78FDB9559C8031C50 + 17: 774962377B8731F2F301B930487518801F, F35B54264711D843D23636BA6CFA3E4C + 18: E9C8D1164F2B196C7305406179B232E45F1F, 2A13E034A136EBC0ED3361737EAD214C + 19: D3DCD242C952C5589E00B65CD826CA87691B8F, 9D624D482042798DB896B55D801EAD98 + 20: 57065B2655D4799C0478FE7E8463A2215E758875, C8FB052F14F9DF6731A9C8B566E71D53 + 21: FF736FDBD23593D9BC9A0D8CA7D819F550EF969322, 5CC3023029790BFD43204B27D52D7D7E + 22: C562B7387B8F1D3DBA22DD1636C9C4AB443F2FF15F70, 195C928EAF88BB4ACBA8A01B4EBAEE6E + 23: D0AC6EA8A804DC261304D4821E6AD7FCC2F0DC1A299B9A, 34FE2034CCF09A98DD50581DA8BCBE39 + 24: B65933A7D7C8EF19C1BDEAABE2B4CE5E821459D953565EF8, 42B20EF142EB228803D6AF47C6482BEB + 25: F1F4FCE842EFEF563F6F047956E6706DC9B178D00D82776D74, 3ECE3050D8C80319821D5F57A7CA7066 + 26: 4A3F10F4E34210A5CA1B81AD4269CBC3FD68AC662BF0E9DC9935, 0BC0724AA9A194D8C75EE6FC8E7F28F1 + 27: 077F3C055303FD669BC1A370B18AA7F31D3C8CBFF5A69381404FBB, 872C7946401BE70E677B79EA13FB0F58 + 28: FD39D32B27FE5BB8E6512C642D490E0AD0866E386580AE115C85ED2B, EE81712EA57DD54DDEE98EAB3285E6EE + 29: B45ED179290A6064188AFF6B722B37F8C3E984EC37AB5F47B353229B12, 186B3AD0C9F60D57E84992CBB2B0F71B + 30: 83FF1FD179D518A414148C15BE566BE4CC3DBE9FF5319A651E862811F152, 4B2942C66565EB9139A83C2EFD549D55 + 31: B8176469E6A0D5797ED6421A871FEECDE48ACF011E394981C43AC917E8FFD5, E9B01383DB1A32E6126BD802A6C6F47E + 32: AB6A0AA29B687D05735167D78DB697BA2478BD14ECD059AE9D1239E7F2AB48FD, A560A30FD87CF28BA66F5B2638567E4B + diff --git a/notes/cipher_tv.txt b/notes/cipher_tv.txt index cbb60c3..c649d26 100644 --- a/notes/cipher_tv.txt +++ b/notes/cipher_tv.txt @@ -1005,6 +1005,222 @@ Key Size: 32 bytes 49: F8B974A4BC134F39BE9B27BD8B2F1129 +Cipher: safer-k64 +Key Size: 8 bytes + 0: 533F0CD7CCC6DDF6 + 1: C3CD66BB1E5E5C17 + 2: 079DFD68F6AF9A79 + 3: 84EB4922264A1204 + 4: 31F3A7D739C7E42C + 5: 381F88FB46E1DCA2 + 6: CAF4AC443E50EF47 + 7: 2914E255DA9BDDBB + 8: A160A24120E4FECC + 9: F748C6009FFBC465 +10: 8B3CB5784846D2B0 +11: 4F98C1621473399B +12: B486B0BC365ABEE9 +13: 314EAB2B4E9F7840 +14: 613FE3637968A8FE +15: 28935352361E1239 +16: 0DCB090233B8EB3C +17: CF0BC7F307586C8B +18: 64DF354F96CB0781 +19: D2B73C6BAACA7FB1 +20: 638FCEEF49A29743 +21: 204C4E0E0C0A8B63 +22: F041EF6BE046D8AA +23: 76954D822F5E2C32 +24: 6700C60971A73C9E +25: 80019293AA929DF2 +26: 8EF4DE13F054ED98 +27: 41DDF9845ABA2B7A +28: B91834079643850C +29: 8F44EC823D5D70DC +30: EC2FF8DE726C84CE +31: 25DF59DC2EA22CB5 +32: FC1130B511794ABB +33: ED3259359D2E68D4 +34: D7773C04804033F6 +35: C1A32C114589251C +36: 51647E61EE32542E +37: B95A8037457C8425 +38: 4F84B3D483F239EE +39: 458401C3787BCA5E +40: F59B5A93FD066F8A +41: 1450E10189CC4000 +42: 0F758B71804B3AB3 +43: 51B744B271554626 +44: B55ADA1ED1B29F0D +45: 585DF794461FEBDA +46: 3790CC4DCA437505 +47: 7F7D46616FF05DFA +48: 6AE981921DFCFB13 +49: FE89299D55465BC6 + + +Cipher: safer-sk64 +Key Size: 8 bytes + 0: 14A391FCE1DECD95 + 1: 16A5418C990D77F4 + 2: EE33161465F7E2DD + 3: AB85A34464D58EC4 + 4: 3D247C84C1B98737 + 5: D88D275545132F17 + 6: 00B45A81780E3441 + 7: 6830FAE6C4A6D0D3 + 8: 93DF6918E1975723 + 9: 15AB9036D02AA290 +10: 0933666F0BA4486E +11: 93F42DEE726D949C +12: 756E7BA3A6D4DE2E +13: 4922DCE8EED38CFD +14: 8EC07AFBD42DF21C +15: E82BEBCFB1D7C6B4 +16: B3EDB4CB62B8A9BA +17: 5521307CA52DD2F3 +18: 54B5D75512E1F8F3 +19: 1A736293F2D460A8 +20: 778C71384545F710 +21: CBC041D3BF742253 +22: 9C47FC0FDA1FE8D9 +23: B84E290D4BF6EE66 +24: FC3E514CE66BB9E3 +25: E8742C92E3640AA8 +26: 4DA275A571BDE1F0 +27: C5698E3F6AC5ED9D +28: AC3E758DBC7425EA +29: B1D316FC0C5A59FD +30: 2861C78CA59069B9 +31: E742B9B6525201CF +32: 2072746EDF9B32A6 +33: 41EF55A26D66FEBC +34: EC57905E4EED5AC9 +35: 5854E6D1C2FB2B88 +36: 492D7E4A699EA6D6 +37: D3E6B9298813982C +38: 65071A860261288B +39: 401EEF4839AC3C2E +40: 1025CA9BD9109F1D +41: 0C28B570A1AE84EA +42: BFBE239720E4B3C5 +43: 09FB0339ACCEC228 +44: DFF2E0E2631B556D +45: ECE375020575B084 +46: 1C4C14890D44EB42 +47: EA9062A14D4E1F7F +48: 82773D9EEFCAB1AB +49: 516C78FF770B6A2F + + +Cipher: safer-k128 +Key Size: 16 bytes + 0: 4D791DB28D724E55 + 1: 53788205114E1200 + 2: 4472BCCAF3DDEF59 + 3: FE9B3640ED11589C + 4: 4DDD7859819857D7 + 5: 6BF901C4B46CC9DB + 6: 930DBFC0DE0F5007 + 7: E89F702158A00D82 + 8: BEB661953BF46D50 + 9: 6F0DA64C0FD101F9 +10: 4EBBCE4E5A37BED8 +11: 996EAA0AF92A09AC +12: AED6BB9522E0B00F +13: DF9C643624A271B4 +14: 2E5C789DD44EF0CF +15: 86A5BA1060177330 +16: 2385DBA4DEBEB4A3 +17: 82E2FC765722094D +18: B3CA2161757695EF +19: F8A4C6081F3ABC06 +20: 6422316E1BEFFAC8 +21: C178511BFBFF380E +22: 049B8CBEDE5942A9 +23: 0E181292C1B1DEFC +24: C347BA0632A49E55 +25: 32FDA46669714F99 +26: 0523743E30C16788 +27: 782BE96A93769ED0 +28: 9F99C9E8BD4A69D8 +29: 104C094F120C926D +30: 1F7EA3C4654D59E6 +31: 90C263629BC81D53 +32: 1803469BE59FED9E +33: 1478C7C176B86336 +34: 362FE111601411FF +35: 6428417432ECC3C8 +36: D74C42FCC6946FC5 +37: 1A8F3A82C78C2BE6 +38: EE22C641DC096375 +39: 59D34A0187C5C021 +40: F68CC96F09686A30 +41: CF8C608BDCC4A7FC +42: D2896AB16C284A85 +43: 8375C5B139D93189 +44: 0F0462F9D8EBAED0 +45: C3359B7CF78B3963 +46: E4F7233D6F05DCC9 +47: 8533D1062397119B +48: 4B300915F320DFCE +49: A050956A4F705DB9 + + +Cipher: safer-sk128 +Key Size: 16 bytes + 0: 511E4D5D8D70B37E + 1: 3C688F629490B796 + 2: 41CB15571FE700C6 + 3: F1CBFE79F0AD23C8 + 4: 0A0DC4AA14C2E8AA + 5: 05740CF7CD1CA039 + 6: 24E886AD6E0C0A67 + 7: EEF14D7B967066BC + 8: 6ABDF6D8AF85EAA0 + 9: 0EB947521357ED27 +10: BDD2C15957F9EC95 +11: 0989B87A74A2D454 +12: 04C793BA2FAB7462 +13: 3DAD2FACDDFA3C45 +14: D1194935CC4E1BD7 +15: BAC0A2C8248FF782 +16: 7DD5894A82298C64 +17: A59F552A4377C08B +18: 8DDDE41AB4586151 +19: 7CC4261B38FFA833 +20: E99204D6584158EC +21: AACC8ED0803CB5C4 +22: C105CA72A7688E79 +23: 3D662FDC35B88C09 +24: A4BCEDC0AE99E30E +25: EAECF9B6024D353C +26: 214651A3D34AFF40 +27: 807099325F9D73C2 +28: 45EC21AEB6B90A24 +29: DCED39526687F219 +30: 2CC248E301D3101D +31: C7F37AB8570BA13C +32: BB9B31A34A39641B +33: 5314570844948CAC +34: 4581F837C02CD4F4 +35: 4E036B1B62303BF3 +36: 7B3B88DE1F5492A4 +37: CEF2865C14875035 +38: 14DE8BEE09A155DE +39: 3AA284C74867161B +40: 3616B4607369D597 +41: 07512F57E75EDEF7 +42: 710D1641FCE64DC2 +43: DB2A089E87C867A2 +44: A192D7B392AA2E2F +45: 8D797A62FBFE6C81 +46: E52CE898E19BF110 +47: 72695C25158CB870 +48: 29F945B733FB498F +49: 27057037E976F3FB + + Cipher: rc2 Key Size: 8 bytes 0: 83B189DE87161805 diff --git a/notes/eax_tv.txt b/notes/eax_tv.txt index 09df008..95cd7c1 100644 --- a/notes/eax_tv.txt +++ b/notes/eax_tv.txt @@ -199,6 +199,82 @@ EAX-twofish (16 byte key) 31: 2DC26D449379997D110309B2A0DC2760FCE8CADB4B14ED580F86C70F69C9BA, EFCB60EB2B25737E256BC76700B198EF 32: 2B1890EB9FC0B8293E45D42D2126F4072754AA54E220C853C5F20FBA86BE0795, 1A1B15BBC287372FB9AF035FB124B6A1 +EAX-safer-k64 (8 byte key) + 0: , 9065118C8F6F7842 + 1: A1, 1926B3F5112C33BA + 2: 2E9A, 5FA6078A0AA7B7C8 + 3: 56FCE2, 984E385F9441FEC8 + 4: C33ACE8A, 24AC1CBBCCD0D00A + 5: 24307E196B, DD2D52EFCA571B68 + 6: 31471EAA5155, EB41C2B36FAAA774 + 7: 03D397F6CFFF62, 7DFBC8485C8B169B + 8: 8FA39E282C21B5B2, 2C7EC769966B36D7 + 9: FEA5402D9A8BE34946, A058E165B5FFB556 + 10: 6CDEF76554CA845193F0, FED516001FFE039A + 11: DC50D19E98463543D94820, 8F9CCF32394498A1 + 12: 42D8DC34F1974FB4EB2535D7, 77F648526BCBB5AF + 13: B75F1299EF6211A6318F6A8EAA, C5086AEA1BE7640B + 14: 1E28D68373330829DD1FFC5D083E, 33EDA06A7B5929A2 + 15: 85529CF87C4706751B0D47CC89CEA6, D031905D6141CBED + 16: FE5CB61BAF93B30ED3C296EE85F51864, CC484888F0ABD922 + +EAX-safer-sk64 (8 byte key) + 0: , 5254AB3079CDCB78 + 1: 75, 798DCF14FEF8F4D1 + 2: 0300, D5FCA75DAC97849C + 3: 520F98, 10E357957CE20898 + 4: 80E2764D, 5C7F46656C6A46EA + 5: C48960CDAA, 3CCF44BD41F01CA8 + 6: E0E60BD9AA2C, EBB493983FCEE79D + 7: D13D8804906A1B, 6EDDCA919978F0B6 + 8: B7AE14C37A343BFB, 2369E38A9B686747 + 9: 5DE326BBCC7D0D35E9, 041E5EE8568E941C + 10: 13494F5B0635BA3D6E53, EAEEA8AFA55141DD + 11: A9BB35B14C831FDA0D83F7, 4002A696F1363987 + 12: E242043A1C355409819FABFC, 63A085B8886C5FDC + 13: 204598B889272C6FE694BDBB4D, 194A1530138EFECE + 14: EE3F39E0823A82615679C664DEBF, 1EFF8134C8BEFB3A + 15: 8579D87FD3B5E2780BC229665F1D1B, A832CD3E1C1C2289 + 16: 74D7290D72DA67C4A9EAD434AE3A0A85, 96BAA615A5253CB5 + +EAX-safer-k128 (16 byte key) + 0: , 7E32E3F943777EE7 + 1: D1, BA00336F561731A7 + 2: F6D7, 8E3862846CD1F482 + 3: 5323B5, BD1B8C27B061969B + 4: A3EC3416, 170BBB9CE17D1D62 + 5: 0C74D66716, 7BD024B890C5CE01 + 6: 6158A630EB37, B5C5BD0652ACB712 + 7: 17F2D0E019947D, F9FF81E2638EC21C + 8: 68E135CC154509C8, AA9EAEF8426886AA + 9: EDB1ABE0B486749C21, 355C99E4651C0400 + 10: DB0C30E9367A72E8F5B2, 631B5671B8A1DB9A + 11: D4E5453D9A4C9DB5170FCE, 75A2DF0042E14D82 + 12: 3F429CC9A550CBDA44107AA7, 2C2977EA13FEBD45 + 13: A7CA22A97C2361171B415E7083, BFE81185F31727A8 + 14: 170F79D8B0E3F77299C44208C5B1, D5ED9F9459DF9C22 + 15: 2E24312D2AE5D5F09D5410900A4BBA, 2FC865CA96EA5A7E + 16: 8F3C49A316BA27067FF2C6D99EC8C846, 9D840F40CDB62E4B + +EAX-safer-sk128 (16 byte key) + 0: , 22D90A75BBA5F298 + 1: 3F, 98C31AB2DE61DE82 + 2: 584D, F4701D4A1A09928C + 3: B9DEAD, 6E221A98505153DA + 4: 06D4A6EB, 0E57C51B96BA13B6 + 5: 7B58B441CA, E28CCF271F5D0A29 + 6: 7950E0D1EC24, 2ACDDE6E38180C07 + 7: 65A4F4E098D7C6, 7DC1C9E9602BACF2 + 8: FEBE4E72BAA0848F, C4607EA3F138BAD9 + 9: 9B7BD6D6D655985AA3, 8B2C58A9530EA6AC + 10: 60C92F925D1478470203, 51E6F5F6DC996F84 + 11: 7B40769370E651F64AA654, 74F1F8A8D3F4B9AF + 12: 7215832C2FB9C54DF7A9C686, 9BF9AEF14F9151D1 + 13: AD0F9C79008572AB8AE2466EFF, F375D0583D921B69 + 14: C05076E2C330A0D25D7CEC80597F, 843C12F84B00A8E0 + 15: D18F0563AB0278140B0CD9A9B07B34, 262B1688E16A171E + 16: 650747091F5C532EE37D2D78EE1EC605, 1BAC36144F9A0E8D + EAX-rc2 (8 byte key) 0: , D6CC8632EEE0F46B 1: 4C, EA19572CB8970CB4 diff --git a/notes/gcm_tv.txt b/notes/gcm_tv.txt new file mode 100644 index 0000000..79d3b8d --- /dev/null +++ b/notes/gcm_tv.txt @@ -0,0 +1,214 @@ +GCM Test Vectors. Uses the 00010203...NN-1 pattern for nonce/header/plaintext/key. The outputs +are of the form ciphertext,tag for a given NN. The key for step N>1 is the tag of the previous +step repeated sufficiently. The nonce is fixed throughout at 13 bytes 000102... + +GCM-aes (16 byte key) + 0: , C6A13B37878F5B826F4F8162A1C8D879 + 1: F1, 397F649A20F3F89A00F45BF230F26B61 + 2: D6B8, 1653F67C9C716D0FC59F3B14154DECBF + 3: 673456, E82EFC79B30CA5235E2DC8BE4C14265D + 4: 26DD7C26, B8D1F4DB845F7D7079DEB8920949C14D + 5: DA62AD1487, 828A42329320764E5FB74D44A6108F4B + 6: FB79F7D51742, 865415BD049E86F3DA2E0B6E25E1A50C + 7: 9D96D1034166BF, 50669247A5B338E183DE5139831CD6A4 + 8: B466050E1330B20A, CB264FA7853A1FFE86E1A07CFA7C7319 + 9: CF16F0B3D9FC6183DF, 647DD6E1F40F385E1DFE6676FB036242 + 10: 14D90928C7236050096F, 930CAAA5536406218885475CA823A973 + 11: 4F2322D66A7079BD7DF519, 3B3931D47413042FAF1313F1041509A3 + 12: F1497906F1D8F4F9E47E4BE9, 469FB0D62828427C2E9BA04041A1424F + 13: 2FAFA2A3EEA4C000702E58D1D4, C9A484FC4ED8644A06060DAE2C3D1568 + 14: 5D707F8ACF319413D220AA2FC2B2, 0EE9AAF5B1CF622ECF6C4F5E5FF4656A + 15: 2C19DBF966D24B2713F82B69934060, 8676246A2F7795ABD435B3C6B4EA6E7A + 16: B3FED6C2315CE6D98729DBE69270A11E, B8AC739AD154744A33E906C34D91BD4B + 17: B2BC44CE088BC3F654B9703D9C691F17B3, BAD8314A171BC0119942136C5876AACC + 18: C6E958E3E9AC836C9626BD66478974D26B0C, 4E6D61833E9DB839117B665A96DC686C + 19: D40FADD078B474EBCE130FB44DDB4824077988, F43E3CD978A6E328AF039CC70E291E1C + 20: E177B3DF83A117E55F255A6C2CD78AFDAFDA307F, EEF1ABAAB9CBE0EE317CC79E7E5E24B8 + 21: DBB4569B3E305E4525F1F7B3D2AFEF226F397E661D, 65ACFB70132EEE1D47319A550A506DB5 + 22: AC2CAF77718DE59131A6B745DE9F3A9897B17580EC71, D8DB9006A9597F640F2594340D69E551 + 23: 8F62022F72A0D769D2D095A55E28832950870B2B44B0BE, A7E196F869071B7BB713E8A2D15627E9 + 24: 37F5640F820384B35F13F8C8C7DC31BDE1E4F29DCFBDA321, D5765C39DBCA72AC89100CCB8864E1DB + 25: 25059BFC302D0F8DD41BB22CF2391D456630C06F1DAF4DFA86, DC2FFD153C788C28D251B78AB8B7388C + 26: 151F158CC4BA9393FDB153C4C72911C120BAB519FAF64719133D, C61915006038BF15DED603832FD179DE + 27: F5DCF4231482F72D02F8B9BE0A41113D35AEA1CD85021CEC978D9C, 9CBD02C557180FBD0868C87A0BEA25AE + 28: 5D88B5554A2ED73054226473676FAA7159CE12B5357D635DDED35B5A, 5AD11CD6B14C59E64B5B26DFBD00FB5C + 29: 5696C7066EA09A30FC8BCBAD96D48A5E5FBCC8756B770F0A89B8711911, B9EA5F3BEF0599D385A9ACEBE4064498 + 30: 1240FED47B305AC1883F8CF137D58E79052B4E686DCA1423A6A2BECBD5F5, 036A5EA5F4F2D0BF397E8896EB7AB03D + 31: AD9517BF392C1EB56D78EDE1C41F3C73B72304DA47F400C390C86B37A50C2A, EB3E026D518EED47F6C927525746AC54 + 32: 2AE1CEED83C6490A7E5752E91532406EAC6FF4B11AA770EFFF1B255FDB77C528, 74BFBC7F120B58FA2B5E988A41EAF7AC + +GCM-rc6 (16 byte key) + 0: , D595FEDAB06C62D8C5290E76ED84601D + 1: 4D, 47A6EDEF8286F9C144B7B51C9BCCCACF + 2: 0085, 9788DDF89843EC51120B132EB0D0F833 + 3: 463701, 673CB8D248E6BECD5A6A7B0B08465EF6 + 4: F5B3222C, 1C424282D7FB427E55285E20FC2ABFF9 + 5: 3A4A8361B2, BD40E631B054F280C7973E5AB3F06B42 + 6: A475866BF2C5, 2067F42FAAA6274270CF9E65D833FDED + 7: 689D0D407172C8, 3BCCFFC64E56D5B753352E1DDD5CCAA3 + 8: D9CE4B051202A1D3, 79B0CCDA3D0B9C9BCF640BC9E6D9CE0D + 9: 0317D68BE098D276B7, AF35043DB6213DC5D4F3DFB8E29EE537 + 10: 154CEF0C6F37AA0A73C4, 61E598A8C6D17B639F9E27AF55DD00F3 + 11: C3DB1B2B6CCC9170B9C05F, 966871DDD6E110711FB9DD733B6B2B3A + 12: E4F22383C75BC0FB0E59C5E8, 971536AF878F4EED68F59046C928EAC8 + 13: 2FBFB99AABC6209FB8664916DD, 68D0BF2144AD1ADECC4074DAE58540C2 + 14: 5FEEDFD09BF89719A34CDCCD2AAA, 64DEB7D5E6891103AA54C0EB366715D0 + 15: E063A076E0C770FB010D26C3AC3EB5, 0CA321B2A7448FEEF84D4E0AD5BA2DA4 + 16: AFB0DB9959F0906BD346C2D81DC5412C, 425627895E2C4C9546D3227975585459 + 17: 79179C0D4D6C5E0741DD4CA1E8CF28C75C, D0188A344A1CEE52272FE6368DB0FB75 + 18: 8A75521139B0DE3C08C9EAEB77D8018A39FE, 47FCC200D8A384320D2F1A5E803A9991 + 19: 0399381D0A975AE3980A9FB75B991C055AF367, 034915370AF94B96A8A4E50FF9B134CC + 20: 8C189094DB13FBE62EA5C4A53C29A428ED587BA2, 99C58F838423033298897841ED526347 + 21: D91F5144B525AF5D47EF4D5F0AF9915447A55927F9, F6750BF7E089515D35B47BC1C65E2E3A + 22: A4E26B554AA277057A5FE3FA08A6138CEEC6D69BB1D8, 7BBEBF52D8251108C7AA1025E213EC44 + 23: 5C1A8C3A46FCA90D73675706313CADFBB90A535A4B3D5A, E35244A2633478BBDAFCC81161F28B80 + 24: D69F7264FC594057B89181B83582D799AE54E9EE4FE8AD48, D4B29E5C25F9477D9345526DBDE9372A + 25: AFD322D0AC4AF38D5B9CBE0DFE85618C001A7A77CD8FFFCB3E, AD06BB9C59D23D258D6A2AEDD946AA20 + 26: 179CA8395CD8E75B4E5EA07D25C8036AF08B1A1C330492523D36, E3704C4341A834C087500E332B7DEAE9 + 27: B9178EF7774684F43F1FCE99A4319B5A4D167B0A848551F562CD7C, 5D5082FB02B9B494D5883DF49DB3B84B + 28: 830FCD15A09EC61245D7DA258E308E76D3B542F2345DBFC11AE983A3, F50C3332F8D91911BDACCFE228565E5C + 29: 179619B8C7EE9B3121405BBED2AC102A027E6C97EAEDB5ECFEB13792EF, 859EBA3BADCE6E5AB271A261B26DE28C + 30: 14264C7E0A154119BF24B7FCF434E81440D42D54738F0BAE55836849AB85, 0B6C9B9CADB1B6EC71CEA090C8C72834 + 31: 0D7A316F8B873F62CF26CFC569179AB11CBF09D3467936A85ADC265B2C9A8F, 866AE7C51EC2D9DEB32748A1C8B61143 + 32: F8FD1F967CD3632805AD7FA8ECB40F530927DD5C49D31FDBAE49738E2315905D, 9CB1CB84A727C9F42555EB566E0A1DEE + +GCM-safer+ (16 byte key) + 0: , F769B436C7FB7C0C822E24BB2B2555D3 + 1: CA, B156298625F5634FA012B23044437807 + 2: 4960, A64C73E890F3D77B2C3B3C76C2D913C6 + 3: DBBB8D, 686651A017F89A22F9FE96533C85C52C + 4: 150AD99A, 177F7DE9E897DACCAB7EACEE3CDE7601 + 5: 077055065F, 48B4309C76CAC37BDF11842311BA6CD3 + 6: B2F8CE062C06, ED04DF96C06959524956E8AC5C338457 + 7: DCE718211410D8, 3F8D8180BDEAC2F018EA81615177CC8F + 8: 0F71E2772402AC83, 2130481B2CA7B4B4C8F3EE73B3B3C28F + 9: B69030734E5ADF753C, 8CC4B62BFBC3EA56CCDBF0ED318C784D + 10: 6B8A91ABC1BF2F2D0176, 86EAAD80D148A48086987A40A5631DEF + 11: 44AD00799EC8E62E34D6A1, 016830D58F06F75E54531B45D9E785F9 + 12: 0C4B9381D78E0F0A78B3CEAA, 4A79C58DAB131A22F172F9177DC4158B + 13: 2C56D4625876524B4D8D5F079B, 7B407F704225B25F1F136C984E564147 + 14: 36424D69BACC56407D345B3D7B4D, EB126C255A2DCFD32F69DD5CB61876C7 + 15: FDD3E091C0420D1A4D4A848757FCC2, D319C5C07134D67BA42A4BF312CD874D + 16: EFAF6F117EA9A4B4B83052BBF5A07DB9, BB09D473FE82257146E7ABC2EFF6F631 + 17: 19B71383C414BAC3EF252FFF09F5ACD777, 526DC9AE6895ED33A34A9A4ADB07E1B6 + 18: 9AB6DFDB930D26E00B3D98DD5AD014E08756, D70B95B20C106A5A03F9B803D2CAC3A0 + 19: EEB3C236C3031DE4C3F94BD746677AE84B271D, 9483BBCBBFDBA1CC5F6392DABA2ACC19 + 20: 3A0EBC7536F8717E8FDAFEDAC39E8F1F43C0627A, 3DA7DC2475466CEDF01EB543870A74FA + 21: 79D28D2F149E1D97E910342DF383FCEECF5AFD4C6A, 2364F33BCF6F07E381F7E26DAF802D83 + 22: F1D7C319BAFB740332CA19AB0C9B71728D3AE69BFAC2, 3D4AEE9780A5C98CBC69606CDDDB31F8 + 23: 1A0D80381A186673FB7B52C40AB6C46A11AB0889333C20, AF5C17E3D0D9724EDC1FC438A16B4EBB + 24: 5E503440B22DD6AE6401BA4355C8791BACC598C9E0F1412E, 156D8221BD61F5C108FC18FB2F50D159 + 25: 7784EFDC6F0FC56FCADAFF17BB52DEB35B64FA19C3F391BDFD, A291E8238EF158A2379692077F70E8D0 + 26: 184B6E18032D1A70CE5027912E447C357C72EEF7B20EF0FB256C, 0FA0138FB9480E0C4C237BF5D6099777 + 27: 7AC8FCB64F35B71C5ED0CCD776B1FF76CE352EB57244085ED34FE8, D995B3C1350CC777878108640C1CADAE + 28: 86C7A01FB2262A8E37FF38CC99BF3EFAEB8B36166D24913BDD3B91DA, 25EC6D9F69168C5FA32C39631B606B55 + 29: 91F5D3E3FE0B1976E2915B8DA3E785F4D55768FD727AEF19FA1552F506, AF902DED55E386F0FC4210C97DB9446E + 30: 7ABF5BD9CB2EFF8382C6D2B28C1B0B25540E434123AC252046BDDA74DA32, 713259EDDA9B1B63EB68E0283D0259DB + 31: 5634B23ACEF2874BE0591BE3268C4538698FF2D93D59B39BC86D0137DACBAD, C4054796AFD335B43C60E7E634122BAF + 32: F26C68C36B1E56449595EA4E162391E0C6A306592949F69797B6C2327E533ADB, 7B392AF776A94983078814B6B8428BFE + +GCM-twofish (16 byte key) + 0: , 6275E8CA35B36C108AD6D5F84F0CC5A3 + 1: 38, A714210792F9ED12A28F25CAE3B3BC5E + 2: 8E2F, 6357C1F125723F2244DAF344CDFCD47B + 3: 900A4C, ED4E0B318346D5B9B646441E946204E9 + 4: 087EAFF8, B871ED95C873F1EFA24EF8B6915F447D + 5: 63FC9EFBD4, 650D0ED98CBECA07040AB97B97129360 + 6: B6081E94AA19, 6A3BDA8030C5A79B6B9087555A1DA67B + 7: E10A7B9CBB20C2, 59EB55DFD0A37C55A869834E597373AF + 8: 94E947FEE05780EE, 354918527F855264E37DB6892E868050 + 9: 9A80C567AA50220862, 814EE57CC9D51D7D900AB4840C4B072F + 10: A8741BE1E42BE207C416, 2B28AFD8ABE20664D8BAD7535F82F11A + 11: 6AB7E3C68B6682023E8190, 5E48B67541FE83969952394F84D29E93 + 12: 4F66FB634EB258CEE2955D84, F2632C2135B6E1144673B0EF73499818 + 13: B29042F3877C2F5E694953C5F6, 03268A30499D57A06AA873EF00160C3C + 14: DCC7B5D9F58C88F54A9611389B8D, 5515426FF7CF2EEA91BE2B3752371CE0 + 15: B665488BCD75FC02A0DF7994B7CF98, B721531E2A317C254FA2ED306ADCF96C + 16: 9535DC8A72645E34F948B71A5159AA9B, 5CEED93DE128044F0471C65AA8F21D29 + 17: 5CBFC61A23D28562FCA929375E5B585327, 3AA842B21631968D1B58B72FEE090EE1 + 18: 2AC3F780B956A933C0B8565EE527173B8CC8, 16EC4B6D8E2CF3CD0D16E7A5F401C78E + 19: 5067FD65870A4EBF6C7FA811A15270E7F8F17D, 9A7563BEDADFA6B6E48F5C13FCEAED6E + 20: E3A65A188077E5DC171CFF30BE8B27F10F015166, BD5B3D84D0C1DD51A3909F849141B57F + 21: 88D0A65C105823E68BE3987CB205AE0C1A27588FCD, B280221AD0BD83E1D6B37F331F326AB5 + 22: 7C56D987FEF6807EEFAFD4C7EB9D72AA0E037979D91E, 686E1268A8DC9CD0192A383EA6C2D975 + 23: B23CCD0A076CB122750B634B9E6551E0585EDEA18C3245, 6DF30A7F0728E2D549AA411AE375E569 + 24: 767BC3AF206E67C9E27A4D7E814F3B3A65D27BB70BA9DD4D, AB2B16C031FB2C8E85B3B2B38A5CBA4E + 25: 9ABF34ABD43705D62F377449461C5DC239A2A86E5A98AFB159, 3DEDEDA85E6BFB53C6F18726CD561604 + 26: FE756344C05CB12AA0673F1C2069A86556E583FF4B7313A0D395, 21CB0E0BABC3C7E547F5CB207295C0EE + 27: B70F16AD19A6B0AF6D8DBF4E98D7D5ADB944D91BD889D9390C3E21, 2AE67812A22C1C785D3BFC184A1C74EA + 28: A6389032AA9D08BDBAAA5E230E5130665FB4F0CB868F3F20C4C5438B, ECA054EFA3F39400A587839C4F0605C7 + 29: A55A41315EAF3A67A0FD0E14C6E04D03A5E38D0F756719F4A0800B290A, 7A5277809D4B65E663603099B4DFFBD8 + 30: E739633579AA6201A024B9873F28412BB08B08B8616D611BC9D07979BD3A, 390038A93AFD326C5CC1525A24CA91AD + 31: ED3266F8B0DAA7C3DB7814427E8139831CFC0EDE668F0DA83FF7090154410D, DE440EC2C6080048BFF3C5455E1BB33F + 32: 4D0F751B55DA3A2E0B28DE59E9680669FCB5984E9C0DB942DBAACDDEF0879731, 62F96CFE31D3D6AAA0B9F5130ED1B21B + +GCM-noekeon (16 byte key) + 0: , EB5A8E30D5C16311864E2D8D32859ACB + 1: 88, EAB88DE1EB7BC784A706B2D7946798D7 + 2: BA1F, DC3CEC6AA324AC7D053EFF7A99AD3069 + 3: 9A1457, 4AB65831DE378DFF71C20249C7BEC05E + 4: 2F9496D6, 800745CF95EAE3A698EDF9EC949D92B7 + 5: 84153177A2, F6A05B654435ABDF5F696C0E0588CB5C + 6: F80B7865C766, 2334D0061FD488D15A6AC8E44EA1F4B9 + 7: 872EA486B4EA9D, 3A49671DE347F675AD7904DDF4255F3D + 8: A4EE5750507FC831, 956D09F7C5FE812C6FB982E1DDBE864A + 9: B5874AC964FBFC1A97, 90FBC75F45BFF58B3A1100393955D0C2 + 10: 92FF5FCF1EC675E02E71, 983C96A7BD4A0DB5D3B877911CE8A6B3 + 11: F7BCA69A9C7033D84A2BA0, D4ECE5BB9FFCBB331A646D9CE8078634 + 12: 5E1041B4554C8CDD14AAF16D, 1EF777F307CB96788B9120FFF8A8BC2F + 13: 7BB7289FCAD209D7992EB7AEDC, E8AEFB830DBAED2B4A790FFEF940A20B + 14: 12776A7C937A648F0A8628AD8C5C, F070283852AC030819EA67BF82C719AA + 15: 7293476D9E935EAE9DEB66F697F662, D6322603671153A1EC1453CDA5978E15 + 16: DC12A86C85E7358919BABB15A3BF5FD7, BBBFA467EBA8124DFEC82DB0137D56B9 + 17: 0CC1DAD00A987F9C57E3660D9417F226E5, BB8AF5A0B5BC79BD11C5D41CA80CDE2C + 18: D0049115D6EB5495FB391CDC494022AEAA48, 682FF357B2BC059765C29AE6CA668D0C + 19: 48FC54A401B4C06CE8567AD298B672191C7E84, 493A4AF4C2A8828FED8442C4EFF877F6 + 20: 90779795821CB1B7DBD97028E29DC1CE7D0CFAE0, E126F485F73B6F7B3894B4CF7E1C5DDE + 21: 8CA5C246C8B7C04BD7171CAE2D1A892D66302433F8, 5D73149A3635A86B3C34DEA5B95CCBCB + 22: DF082B665F7A952B2604C04554B81393FCC7C0B816C8, D3569ED7D431176B286EF22414E4CBA8 + 23: 761908530C9069E189649ED24B6A68A89B067C31E9868C, A258BCD83D3FBC7AE2AEF7516025AB36 + 24: 717048F5A31F3C89D3704F90069AC5D5174118770C65BDA1, 067EBF18F7E3DF4EA13F9ABAC682C2A2 + 25: 08C6FCC5D3099347C3FEBA3858A6C22C51298CB591DDB77827, B57BFBA40BE99DF5031918A1A4E2CA80 + 26: 2CC53EF7EB954234E64CD4D60FB1D7157A489ABABC10900FFCDB, 236E769611D16EB7F463B7578770F886 + 27: 2556B46F2E831223D632F2691329A874F517687AF81B8322AC55D7, E213A90DBC31DC261A45A9AE41CFEEC3 + 28: 71241792728594D69791B80AD6DBC6417D1D14D222DF5E6F834B82C8, 601F97617708B1945BCDA8A82496EFB1 + 29: 5003DC2EAAA23F9E2221CCBB9E20116692CCC99B3CFBD0DDD3A8491E7C, 3743155B792012845550205C8949B73E + 30: D0589675357E850333F854FBA160688F06D122DEC00CC2620DA0B2770765, 20E085752FC4D37791C22501ED1DB6AD + 31: 645B46D2D114EE7329F14AC1D94E6817EB385EB80C61F014F90530749079EC, 8A18DE86F9555A1070D0BFEDAC15B14F + 32: 068389206D37BF5A41C58075FC98901C3B42E6F2F13C09F4E92524021BB1C1C8, 370B86914D63CFEE8303D538A6BEA0E7 + +GCM-anubis (16 byte key) + 0: , A0061C2F3B2295BFA33BC74C037EA8DA + 1: ED, 9E5648DCE40DE37B56C557D26CB18D83 + 2: 6719, A6605253C59A101FF85C5102CE92BE45 + 3: B8873D, 13F3E3ED3646BB296EE4ED5D6379A21B + 4: 5AA6E2CB, 1812E8385D15B5BAE043E4E860BEF490 + 5: 4F6F4CD8E9, 8A80BC5E08929C42A5A74C5D9ACC0C6D + 6: 2F0D8B483CE4, 316F588F78FC6A9196C97CE59B9B63B6 + 7: 82D885FDE1F948, 7160BF556614511F53738A92B5277056 + 8: E4931462AD41B6DC, 7CE24C4D6B499975FCB72B5E2275ED56 + 9: 503AA70BE698BC5B41, 10EA0C61FDBA8FF7B4E9927BCCEFD911 + 10: 6B2D213D14B5D25EBE36, DC3222AED12EE26D3D14E2E733EDB2A7 + 11: 7D8B0BC1B7443E7267371E, FCACFC73E391865BE86E041F51C45E81 + 12: 9EF3BF8609E133BEB10565AF, D84326D4CAC9D5B74FCFD8CBAFE79E77 + 13: 59AE7B1FDE1178CEE7F63C4894, E1BCFCDCA86CAB9C684F7D21962D580D + 14: 564E7B8BAC5582A3BF1178916569, 54804D8DF4D7577EF65C15487695F840 + 15: 758A6DC437C8821274B0F16F911BAA, 19DD27500915F425F34F67CC2374DC36 + 16: 0468C94A88A27AEEE2B3A973065E53CC, C743996C6F49363B2F4613F24703EF7E + 17: 3B0CABA5EEE44B7BFF0D726ECED54763FF, 14D9D09815BCD91DCCE2F5AE1A9929CF + 18: 5B945D83B98C43B0248F9BC0479E332869AB, 67A275F0313D4245B1965411CFCC8F17 + 19: 97332441CA96DE8553A3C6D898FC6D90C86DBF, 73150EC3D6327E3FC8015A6192652D3B + 20: B9A1778FAF9767160D0D87816ECE1B99AA727087, 0C173D3C4078392CE377313C48D2BAE8 + 21: 5882B73911C7D26EFDCCA3AED2EDC8A8BFFE75B1F8, 8F8C535639A0B59537E590C7FC9D2E53 + 22: 70AEBED8CCFFF6E5CF06F3E841D12387EF8D6C7B4BDE, 4B00C27FCA9BEB82331CC8EB13DCC580 + 23: 345CCB52BC20DC5F1BF5EEDF5D72A6C48F402557FFD342, 1A790A39573B853DBB8E2E73B7331014 + 24: 0637C78A817E91D63CE18CEAF8D65C6107283A90C5A97842, 52786CB81724E12C76A0D23D4680E36B + 25: 59526D1E86A473DFB720FF25E97D6571077845F73C5E8322F1, 369FBA7823FC83D727FFD25D10130987 + 26: 2933BB4E7603C313B62332827601F8189E14C1F08EA547E15AB5, 204520E365DAFF6551B01562A4CEFDFB + 27: A4098CF2A48A1DC2BCCE65CCE8DF825AF51E7E5F94B6186FF85D77, 9833EBB9A1D5CD0356E023E2C3761C2B + 28: 26557B942FD6913D806672EB01526DBD5D6F532F78AB6759DE3415C5, EDAACDD101BC40EE6530D8B5DC031F31 + 29: DB92C3D77DF0C8F4C98845AA9AD43FB800192E57A53E083862B7E3FAF0, 628DEB1E345303A40700289052080FF8 + 30: FC57BFAC2C77781723C2B721886D44ED67A52D9AD827874BC4EEC0A97281, 9A222DBC47B4AB4E520D3CC5850D4DEF + 31: 72DFB9E91A78EAFE758B4542206A4A957B4523A58428398C11BCF2AEAE1938, 307D0B876130E82804C1167E03B69B2F + 32: 7275C6EBDC2680DFCB73326A987D2FBCE83E40A9AEFE6351CFDA7251A6FE10A6, 895E6EEAA9BD88594903325A063CA45F + diff --git a/notes/ocb_tv.txt b/notes/ocb_tv.txt index 6e0ff9d..6429228 100644 --- a/notes/ocb_tv.txt +++ b/notes/ocb_tv.txt @@ -199,6 +199,82 @@ OCB-twofish (16 byte key) 31: F175230606040ADACEBAFE4D58BBD140B2D45E8BF7E5C904510B58E4B53D3F, DAF579E1A12481D39F4DCFB7C28794B1 32: 261388D491EF1CB92C261FD9B91CAD5B95440DE0A747144EB8697699F600801D, 749056EBEAF4F20CD8746AA8C8846C47 +OCB-safer-k64 (8 byte key) + 0: , 0EDD2A1AB692AA7A + 1: 3E, 306F814F3C2C109E + 2: 0593, 063D19B734C34715 + 3: CA72C6, DF6DAAFAD91BE697 + 4: 08924AEE, 15095FA49E789483 + 5: 359908A6CD, 16CB7F0741BA4091 + 6: 97F3BD820CF4, A59DB15B67B95EE8 + 7: 0A267201AC039E, B4FFC31DBCD8284A + 8: 9F6ACD9705C9ECC5, 6B41A938F0B1CAEB + 9: F355D5A937DD1582C2, 9D1F932E521CB955 + 10: ED39758CAF89E7932E48, 398EF517015F118F + 11: D8ACF19363A0E0ADC9321B, F98B2A30217766AA + 12: F8F54A8202B0F281ED610F33, 36EF7FA4A20E04B7 + 13: 0F8677DF64B5982DB6E2299140, 4DED2DA806834C81 + 14: 0C357A9DC321C93B3872881503B0, 7814D1C0C6A8900A + 15: 10B6B1A261C3015A18110AD200A7B6, 9A814D6D2BAD850C + 16: AA9EA9D1BA7818C0D2EBF23781A5467D, 236A24FC98826702 + +OCB-safer-sk64 (8 byte key) + 0: , 76F16BDCE55B3E23 + 1: 63, F34B0B471F6F8F75 + 2: 8651, D7EFE17943D35193 + 3: D45504, 263224E50E7E9E75 + 4: 57B414C3, A553D6CABCA0F285 + 5: 4976E3B303, AC5E9969F739EBD9 + 6: F10AB8EB94E0, 8301FFE68848D46D + 7: 6E954593AC427D, C1CF93BBC0F92644 + 8: F48F44441B898C0F, 698FFAED1A95E8E4 + 9: 1DC60156D62782E3D0, 6AFF0DCC65D4C933 + 10: 71920ADC8997CB8B3A72, 1C101C6A27CFBBBD + 11: 890ED7492ED914AC20391B, F66DCD6205D945C6 + 12: 1B9FAB84A8748BAC187C7393, B450757FCAFAAD52 + 13: B4C89E1BB280DBC265E43ACE15, AE6BB3D2E6A371FF + 14: 24B0C28944BDF22048E2E86644F5, 84E93E2191CEF17A + 15: 8F2D5694D55EE235168AAA735943AF, 514252AEF2F2A2D9 + 16: 568B7E31FFDA726718E40397CFC8DCC6, 3C80BA7FCA9E419E + +OCB-safer-k128 (16 byte key) + 0: , 4919F68F6BC44ABC + 1: 65, C6785F7BE4DE54D3 + 2: E1B0, C197C93B63F58355 + 3: BB7247, DFE092EF8184443B + 4: 38C2D022, 943FD999227C5596 + 5: D71E4FD0ED, 51040FE9A01EA901 + 6: C4B211EADC2A, 329429BE3366F22F + 7: 426DEB3FC3A4BC, CF1C976F6A19CE88 + 8: A6F813C09CE84800, 98D9FF427B3BD571 + 9: 4D1A9948FD157814B4, 5A389FAEEB85B8C6 + 10: EC3EA142C3F07F5A9EEB, 31E26E13F032A48F + 11: A75FB14365D1533CD3FBE7, 8EF01ACC568C0591 + 12: 891582B5853DD546FF3EA071, E013CFFE43219C21 + 13: 54CA848C49DCDEE076780F21F4, 298EFC7B4D6B6CFE + 14: EA7611C69A60F1A2EF71D6A7762D, 7D9AA51CFCEC8101 + 15: B2D1A211BC524B965A084BB4B21710, 7B2AC0EEB5216892 + 16: 5E81F1BFA270E804A488C9BFAB75811D, A67F627CE1E37851 + +OCB-safer-sk128 (16 byte key) + 0: , E523C6DBB3CA178D + 1: 5E, B1CB7EBE5780DF98 + 2: F4D8, 8036235F2BE7A817 + 3: 4FE268, 123320394EAC24F6 + 4: A5BA02B4, B8276B5E027D45DA + 5: 1571859CCC, 29406C5F2DF2CFC4 + 6: CA1E47447B95, 5D4FAF8FD5341791 + 7: 8710DB37022D96, E10040FEA9AEA9C2 + 8: 205990DC9A34DA3C, AE25CB49AA7A697B + 9: 757AFCB3191DC811C3, AA8CADA8638D6118 + 10: 6994F8C153522361BB92, 1BCEE09E928EB18B + 11: A86FA0CDD051BB60AF5AA8, 50A38F8E9889354D + 12: 8D3FD3EB7FF2269AACFD24BA, CB51CF84CEFC45F0 + 13: 03D2A313925D9490FC5547F95F, A1FF9D72E11C420B + 14: D77C0F0F600FE92F14F479FA457C, 1EBE1B4B9685EDFA + 15: 0CAF0A8BEB864E26058C7DF8EBA0EB, 1B153DDAE807561F + 16: 113D12716DFE0596A2F30C875EC6BA0E, C61F5AC0245154A6 + OCB-rc2 (8 byte key) 0: , 1A073F25FF5690BE 1: F4, 3D3221E92E40F634 diff --git a/notes/omac_tv.txt b/notes/omac_tv.txt index 25f026f..56d8da6 100644 --- a/notes/omac_tv.txt +++ b/notes/omac_tv.txt @@ -199,6 +199,82 @@ OMAC-twofish (16 byte key) 31: C24FCA5DD4AE0DF2BFF17364D17D6743 32: DC6738080478AF9AF7CA833295031E06 +OMAC-safer-k64 (8 byte key) + 0: 726FE2DD40A43924 + 1: 2A138B65EB352621 + 2: 9588A1B53E29616C + 3: C025DEFDE1A59850 + 4: 73D062F1B6D8E003 + 5: 944598A2FC8A2D76 + 6: B176C25D8CAFFC98 + 7: 14F05014DE6A090A + 8: A7B9847B2CE22D0F + 9: FCD71310CBAA3A62 + 10: BFF00CE5D4A20331 + 11: BEE12A2171333ED5 + 12: 333FD849BEB4A64A + 13: D048EC7E93B90435 + 14: F04960356689CFEF + 15: 9E63D9744BF1B61A + 16: 7C744982F32F8889 + +OMAC-safer-sk64 (8 byte key) + 0: E96711BA37D53743 + 1: 7DCFF26A03509FE1 + 2: 0A20EF19C8EE9BF2 + 3: FE2883748A6963CF + 4: 557060195B820A18 + 5: 771A7931FBBE5C0F + 6: 6BDBCE5F96CF91D8 + 7: F3B924CCE8724595 + 8: EC7191286D83C2C3 + 9: 94F55B19BB7A8AC1 + 10: 2189F4F2B06A8CA4 + 11: 99853DAEBCA33A46 + 12: 66EAC37A033802D7 + 13: 845D7AA866F8A8AD + 14: 33A874DFECAC22AC + 15: 63DD9F7A7F3683DF + 16: EAC277D951676C44 + +OMAC-safer-k128 (16 byte key) + 0: 8037B89AF193F129 + 1: FF2314E87BA6AFE1 + 2: C3243DF896B61D85 + 3: 0F61C715CE821AB8 + 4: EBFDC6A9CFD2F5A4 + 5: AB6497D7AF2C7FFF + 6: C920CEEB7C1819C2 + 7: 3E186951B545A7E5 + 8: 5EA36A93C94AF4AC + 9: 6A2C59FAE33709BE + 10: BF1BAFAF9FC39C19 + 11: 69EB6EF046677B7C + 12: CDDCEE6B20453094 + 13: A3833BD3FED6895C + 14: B6C05E51F01E049B + 15: 90A2D0EAB739D39B + 16: 07BF607A161D0A66 + +OMAC-safer-sk128 (16 byte key) + 0: 5E8B137A3946A557 + 1: 0228FA66B13F3C7E + 2: A6F9BBAFF050DCDD + 3: F75880F684A796CE + 4: E0AEFB8E32040EBD + 5: 9F65D658B86D310F + 6: 3FA52804FB46CCAA + 7: 2F6D12D199FCD2FB + 8: CB56AF60AFB4D2BB + 9: 8E6F0FF6FDD262FD + 10: 490245BE3CCCEDE2 + 11: EFD319AE46C73005 + 12: 43E00E545C848995 + 13: 10444B41ECA15EBE + 14: 521775C389D5BE71 + 15: 9B683EF8B097FEBA + 16: 3C5D746EED09530A + OMAC-rc2 (8 byte key) 0: F001FE9BBC3A97B0 1: 8F8DC9C952897FBD diff --git a/notes/pmac_tv.txt b/notes/pmac_tv.txt index ed0b7fe..e0a1900 100644 --- a/notes/pmac_tv.txt +++ b/notes/pmac_tv.txt @@ -199,6 +199,82 @@ PMAC-twofish (16 byte key) 31: 0D06F2FAEC5AA404A4087AAEBC4DBB36 32: 0F396FE9E3D9D74D17EB7A0BF603AB51 +PMAC-safer-k64 (8 byte key) + 0: 2E49792C78C1DA52 + 1: 7A5136F4FE617C57 + 2: 6FC8575F6F3D78EC + 3: 7C0373CAEAAA640B + 4: 9D469E7FF6C35D31 + 5: 7755D62DD7D88112 + 6: ADD9E7855A958C9F + 7: 752D29BA8150F18E + 8: 0954649A99596104 + 9: 05D4D75A9FAE233D + 10: 1AADAFD7B4B250DA + 11: E7A8F31ED74DA32B + 12: 1A74DF61BDB9DF94 + 13: C38A67B1955C4E0D + 14: EBADAA44746ADF16 + 15: C0BFBB092CE81D8E + 16: 984975657F3FF2B0 + +PMAC-safer-sk64 (8 byte key) + 0: E8917E1629E7403E + 1: AE8061A5E412A647 + 2: C969771CE5A9B0C6 + 3: 78159C01D0A3A5CB + 4: 1DD4382A8FC81921 + 5: 4086880FD863C048 + 6: A520B45600A3FA1D + 7: 0F0AB5118D7506C4 + 8: 22E315F2DD03BCC6 + 9: 5ECB5561EE372016 + 10: 446A9B2BCB367AD6 + 11: B2107FE2EB411AE9 + 12: 5A539B62FB5893DF + 13: F44EE1EB3278C2BA + 14: 293FEA56D1F6EA81 + 15: F38F614D2B5F81C4 + 16: AB23F7F8F4C12A7E + +PMAC-safer-k128 (16 byte key) + 0: 7E0BDE11EC82FDE6 + 1: 8942FB017A135520 + 2: 0B073E6D0F037A02 + 3: DBF88439D671ED4F + 4: B89427ED1121069A + 5: AA8573DAC66D2315 + 6: 12DA3144BEF13FF2 + 7: EF80413CBA281B3A + 8: DFA7114D8505EEBD + 9: AE53607F3E6F4A54 + 10: 3F2C9395CFB9F78F + 11: 67EB7C5F02760AED + 12: 3EF4CBB4AB5B8D1F + 13: 83B63AFA78795A92 + 14: 5DE400951766992A + 15: AA8791A45237CF83 + 16: 7743B18704B037CF + +PMAC-safer-sk128 (16 byte key) + 0: 8F1597FFCF6FB7C1 + 1: AFF8BD8FF9F3888A + 2: 65F89D82869D8B42 + 3: CBE1F06476B2D5BD + 4: 4878D47FDFECE23E + 5: 4751A9E6D61AB2A2 + 6: 003AC162AED4DED8 + 7: 1F617A5555092C22 + 8: 088EE0C35B607153 + 9: F840B485086F9908 + 10: BA99E0FB5D7D0976 + 11: F04AF6DC4BAF6887 + 12: 5DBBE40AF2F67E4E + 13: 7F52A93E87E29C9D + 14: 7B26A14A4BD5B709 + 15: C34F26E08C64F26B + 16: 291A41D479EC1D2A + PMAC-rc2 (8 byte key) 0: E5AF80FAC4580444 1: 6A15D6211EB4FF99 diff --git a/parsenames.pl b/parsenames.pl index 9047cd1..d6466c5 100644 --- a/parsenames.pl +++ b/parsenames.pl @@ -11,10 +11,12 @@ print $b; foreach my $obj (@a) { $len = $len + length($obj); $obj =~ s/\*/\$/; - if ($len > 80) { + if ($len > 100) { printf "\\\n"; $len = length($obj); } print "$obj "; } +if ($ARGV[0] eq "HEADERS") { print "testprof/tomcrypt_test.h"; } + print "\n\n"; diff --git a/src/ciphers/aes/aes.c b/src/ciphers/aes/aes.c index 7df04f2..e698efd 100644 --- a/src/ciphers/aes/aes.c +++ b/src/ciphers/aes/aes.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ /* AES implementation by Tom St Denis @@ -39,6 +39,7 @@ #define SETUP rijndael_setup #define ECB_ENC rijndael_ecb_encrypt #define ECB_DEC rijndael_ecb_decrypt +#define ECB_DONE rijndael_done #define ECB_TEST rijndael_test #define ECB_KS rijndael_keysize @@ -47,7 +48,8 @@ const struct ltc_cipher_descriptor rijndael_desc = "rijndael", 6, 16, 32, 16, 10, - SETUP, ECB_ENC, ECB_DEC, ECB_TEST, ECB_KS + SETUP, ECB_ENC, ECB_DEC, ECB_TEST, ECB_DONE, ECB_KS, + NULL, NULL, NULL, NULL, NULL, NULL, NULL }; const struct ltc_cipher_descriptor aes_desc = @@ -55,7 +57,8 @@ const struct ltc_cipher_descriptor aes_desc = "aes", 6, 16, 32, 16, 10, - SETUP, ECB_ENC, ECB_DEC, ECB_TEST, ECB_KS + SETUP, ECB_ENC, ECB_DEC, ECB_TEST, ECB_DONE, ECB_KS, + NULL, NULL, NULL, NULL, NULL, NULL, NULL }; #else @@ -63,13 +66,15 @@ const struct ltc_cipher_descriptor aes_desc = #define SETUP rijndael_enc_setup #define ECB_ENC rijndael_enc_ecb_encrypt #define ECB_KS rijndael_enc_keysize +#define ECB_DONE rijndael_enc_done const struct ltc_cipher_descriptor rijndael_enc_desc = { "rijndael", 6, 16, 32, 16, 10, - SETUP, ECB_ENC, NULL, NULL, ECB_KS + SETUP, ECB_ENC, NULL, NULL, ECB_DONE, ECB_KS, + NULL, NULL, NULL, NULL, NULL, NULL, NULL }; const struct ltc_cipher_descriptor aes_enc_desc = @@ -77,7 +82,8 @@ const struct ltc_cipher_descriptor aes_enc_desc = "aes", 6, 16, 32, 16, 10, - SETUP, ECB_ENC, NULL, NULL, ECB_KS + SETUP, ECB_ENC, NULL, NULL, ECB_DONE, ECB_KS, + NULL, NULL, NULL, NULL, NULL, NULL, NULL }; #endif @@ -707,6 +713,15 @@ int ECB_TEST(void) #endif /* ENCRYPT_ONLY */ + +/** Terminate the context + @param skey The scheduled key +*/ +void ECB_DONE(symmetric_key *skey) +{ +} + + /** Gets suitable key size @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. diff --git a/src/ciphers/aes/aes_tab.c b/src/ciphers/aes/aes_tab.c index 135b8f9..0ad1dfe 100644 --- a/src/ciphers/aes/aes_tab.c +++ b/src/ciphers/aes/aes_tab.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ /* The precomputed tables for AES */ /* diff --git a/src/ciphers/anubis.c b/src/ciphers/anubis.c index d4543d9..7e2af60 100644 --- a/src/ciphers/anubis.c +++ b/src/ciphers/anubis.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ /** @@ -27,7 +27,9 @@ const struct ltc_cipher_descriptor anubis_desc = { &anubis_ecb_encrypt, &anubis_ecb_decrypt, &anubis_test, - &anubis_keysize + &anubis_done, + &anubis_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL }; #define MIN_N 4 @@ -1168,7 +1170,7 @@ int anubis_test(void) int keylen; unsigned char pt[16], ct[16], key[40]; } tests[] = { -#ifndef ANUBIS_TWEAK +#ifndef ANUBIS_TWEAK /**** ORIGINAL ANUBIS ****/ /* 128 bit keys */ { @@ -1325,24 +1327,24 @@ int anubis_test(void) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } -} -#else - /**** Tweaked ANUBIS ****/ +} +#else + /**** Tweaked ANUBIS ****/ /* 128 bit keys */ { - 16, + 16, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0xB8, 0x35, 0xBD, 0xC3, 0x34, 0x82, 0x9D, 0x83, - 0x71, 0xBF, 0xA3, 0x71, 0xE4, 0xB3, 0xC4, 0xFD }, + { 0xB8, 0x35, 0xBD, 0xC3, 0x34, 0x82, 0x9D, 0x83, + 0x71, 0xBF, 0xA3, 0x71, 0xE4, 0xB3, 0xC4, 0xFD }, { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, { 16, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0xE6, 0x14, 0x1E, 0xAF, 0xEB, 0xE0, 0x59, 0x3C, - 0x48, 0xE1, 0xCD, 0xF2, 0x1B, 0xBA, 0xA1, 0x89 }, + { 0xE6, 0x14, 0x1E, 0xAF, 0xEB, 0xE0, 0x59, 0x3C, + 0x48, 0xE1, 0xCD, 0xF2, 0x1B, 0xBA, 0xA1, 0x89 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }, @@ -1352,8 +1354,8 @@ int anubis_test(void) 20, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x97, 0x59, 0x79, 0x4B, 0x5C, 0xA0, 0x70, 0x73, - 0x24, 0xEF, 0xB3, 0x58, 0x67, 0xCA, 0xD4, 0xB3 }, + { 0x97, 0x59, 0x79, 0x4B, 0x5C, 0xA0, 0x70, 0x73, + 0x24, 0xEF, 0xB3, 0x58, 0x67, 0xCA, 0xD4, 0xB3 }, { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } @@ -1361,8 +1363,8 @@ int anubis_test(void) 20, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0xB8, 0x0D, 0xFB, 0x9B, 0xE4, 0xA1, 0x58, 0x87, - 0xB3, 0x76, 0xD5, 0x02, 0x18, 0x95, 0xC1, 0x2E }, + { 0xB8, 0x0D, 0xFB, 0x9B, 0xE4, 0xA1, 0x58, 0x87, + 0xB3, 0x76, 0xD5, 0x02, 0x18, 0x95, 0xC1, 0x2E }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } @@ -1373,8 +1375,8 @@ int anubis_test(void) 24, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x7D, 0x62, 0x3B, 0x52, 0xC7, 0x4C, 0x64, 0xD8, - 0xEB, 0xC7, 0x2D, 0x57, 0x97, 0x85, 0x43, 0x8F }, + { 0x7D, 0x62, 0x3B, 0x52, 0xC7, 0x4C, 0x64, 0xD8, + 0xEB, 0xC7, 0x2D, 0x57, 0x97, 0x85, 0x43, 0x8F }, { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } @@ -1382,8 +1384,8 @@ int anubis_test(void) 24, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0xB1, 0x0A, 0x59, 0xDD, 0x5D, 0x5D, 0x8D, 0x67, - 0xEC, 0xEE, 0x4A, 0xC4, 0xBE, 0x4F, 0xA8, 0x4F }, + { 0xB1, 0x0A, 0x59, 0xDD, 0x5D, 0x5D, 0x8D, 0x67, + 0xEC, 0xEE, 0x4A, 0xC4, 0xBE, 0x4F, 0xA8, 0x4F }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } @@ -1394,8 +1396,8 @@ int anubis_test(void) 28, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x68, 0x9E, 0x05, 0x94, 0x6A, 0x94, 0x43, 0x8F, - 0xE7, 0x8E, 0x37, 0x3D, 0x24, 0x97, 0x92, 0xF5 }, + { 0x68, 0x9E, 0x05, 0x94, 0x6A, 0x94, 0x43, 0x8F, + 0xE7, 0x8E, 0x37, 0x3D, 0x24, 0x97, 0x92, 0xF5 }, { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -1404,8 +1406,8 @@ int anubis_test(void) 28, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0xDD, 0xB7, 0xB0, 0xB4, 0xE9, 0xB4, 0x9B, 0x9C, - 0x38, 0x20, 0x25, 0x0B, 0x47, 0xC2, 0x1F, 0x89 }, + { 0xDD, 0xB7, 0xB0, 0xB4, 0xE9, 0xB4, 0x9B, 0x9C, + 0x38, 0x20, 0x25, 0x0B, 0x47, 0xC2, 0x1F, 0x89 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -1417,8 +1419,8 @@ int anubis_test(void) 32, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x96, 0x00, 0xF0, 0x76, 0x91, 0x69, 0x29, 0x87, - 0xF5, 0xE5, 0x97, 0xDB, 0xDB, 0xAF, 0x1B, 0x0A }, + { 0x96, 0x00, 0xF0, 0x76, 0x91, 0x69, 0x29, 0x87, + 0xF5, 0xE5, 0x97, 0xDB, 0xDB, 0xAF, 0x1B, 0x0A }, { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -1427,8 +1429,8 @@ int anubis_test(void) 32, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x69, 0x9C, 0xAF, 0xDD, 0x94, 0xC7, 0xBC, 0x60, - 0x44, 0xFE, 0x02, 0x05, 0x8A, 0x6E, 0xEF, 0xBD }, + { 0x69, 0x9C, 0xAF, 0xDD, 0x94, 0xC7, 0xBC, 0x60, + 0x44, 0xFE, 0x02, 0x05, 0x8A, 0x6E, 0xEF, 0xBD }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -1440,8 +1442,8 @@ int anubis_test(void) 36, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x0F, 0xC7, 0xA2, 0xC0, 0x11, 0x17, 0xAC, 0x43, - 0x52, 0x5E, 0xDF, 0x6C, 0xF3, 0x96, 0x33, 0x6C }, + { 0x0F, 0xC7, 0xA2, 0xC0, 0x11, 0x17, 0xAC, 0x43, + 0x52, 0x5E, 0xDF, 0x6C, 0xF3, 0x96, 0x33, 0x6C }, { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -1451,8 +1453,8 @@ int anubis_test(void) 36, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0xAD, 0x08, 0x4F, 0xED, 0x55, 0xA6, 0x94, 0x3E, - 0x7E, 0x5E, 0xED, 0x05, 0xA1, 0x9D, 0x41, 0xB4 }, + { 0xAD, 0x08, 0x4F, 0xED, 0x55, 0xA6, 0x94, 0x3E, + 0x7E, 0x5E, 0xED, 0x05, 0xA1, 0x9D, 0x41, 0xB4 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -1465,8 +1467,8 @@ int anubis_test(void) 40, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0xFE, 0xE2, 0x0E, 0x2A, 0x9D, 0xC5, 0x83, 0xBA, - 0xA3, 0xA6, 0xD6, 0xA6, 0xF2, 0xE8, 0x06, 0xA5 }, + { 0xFE, 0xE2, 0x0E, 0x2A, 0x9D, 0xC5, 0x83, 0xBA, + 0xA3, 0xA6, 0xD6, 0xA6, 0xF2, 0xE8, 0x06, 0xA5 }, { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -1476,15 +1478,15 @@ int anubis_test(void) 40, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x86, 0x3D, 0xCC, 0x4A, 0x60, 0x34, 0x9C, 0x28, - 0xA7, 0xDA, 0xA4, 0x3B, 0x0A, 0xD7, 0xFD, 0xC7 }, + { 0x86, 0x3D, 0xCC, 0x4A, 0x60, 0x34, 0x9C, 0x28, + 0xA7, 0xDA, 0xA4, 0x3B, 0x0A, 0xD7, 0xFD, 0xC7 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } -} -#endif +} +#endif }; int x, y; unsigned char buf[2][16]; @@ -1509,6 +1511,13 @@ int anubis_test(void) #endif } +/** Terminate the context + @param skey The scheduled key +*/ +void anubis_done(symmetric_key *skey) +{ +} + /** Gets suitable key size @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. diff --git a/src/ciphers/blowfish.c b/src/ciphers/blowfish.c index d136794..2f0385d 100644 --- a/src/ciphers/blowfish.c +++ b/src/ciphers/blowfish.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ /** @file blowfish.c @@ -25,7 +25,9 @@ const struct ltc_cipher_descriptor blowfish_desc = &blowfish_ecb_encrypt, &blowfish_ecb_decrypt, &blowfish_test, - &blowfish_keysize + &blowfish_done, + &blowfish_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL }; static const ulong32 ORIG_P[16 + 2] = { @@ -553,6 +555,13 @@ int blowfish_test(void) #endif } +/** Terminate the context + @param skey The scheduled key +*/ +void blowfish_done(symmetric_key *skey) +{ +} + /** Gets suitable key size @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. diff --git a/src/ciphers/cast5.c b/src/ciphers/cast5.c index 2a2c714..2b8e4a5 100644 --- a/src/ciphers/cast5.c +++ b/src/ciphers/cast5.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ /** @@ -25,7 +25,9 @@ const struct ltc_cipher_descriptor cast5_desc = { &cast5_ecb_encrypt, &cast5_ecb_decrypt, &cast5_test, - &cast5_keysize + &cast5_done, + &cast5_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL }; static const ulong32 S1[256] = { @@ -683,6 +685,13 @@ int cast5_test(void) #endif } +/** Terminate the context + @param skey The scheduled key +*/ +void cast5_done(symmetric_key *skey) +{ +} + /** Gets suitable key size @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. diff --git a/src/ciphers/des.c b/src/ciphers/des.c index a8c4500..d42c5fa 100644 --- a/src/ciphers/des.c +++ b/src/ciphers/des.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" @@ -29,7 +29,9 @@ const struct ltc_cipher_descriptor des_desc = &des_ecb_encrypt, &des_ecb_decrypt, &des_test, - &des_keysize + &des_done, + &des_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL }; const struct ltc_cipher_descriptor des3_desc = @@ -41,7 +43,9 @@ const struct ltc_cipher_descriptor des3_desc = &des3_ecb_encrypt, &des3_ecb_decrypt, &des3_test, - &des3_keysize + &des3_done, + &des3_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL }; static const ulong32 bytebit[8] = @@ -1476,7 +1480,7 @@ static void _desfunc(ulong32 *block, const ulong32 *keys) work = ((leftt >> 8) ^ right) & 0x00ff00ffL; right ^= work; leftt ^= (work << 8); - // -- + /* -- */ work = ((leftt >> 2) ^ right) & 0x33333333L; right ^= work; leftt ^= (work << 2); @@ -1665,7 +1669,7 @@ int des_test(void) #else int err; static const struct des_test_case { - int num, mode; // mode 1 = encrypt + int num, mode; /* mode 1 = encrypt */ unsigned char key[8], txt[8], out[8]; } cases[] = { { 1, 1, { 0x10, 0x31, 0x6E, 0x02, 0x8C, 0x8F, 0x3B, 0x4A }, @@ -1837,6 +1841,21 @@ int des3_test(void) #endif } +/** Terminate the context + @param skey The scheduled key +*/ +void des_done(symmetric_key *skey) +{ +} + +/** Terminate the context + @param skey The scheduled key +*/ +void des3_done(symmetric_key *skey) +{ +} + + /** Gets suitable key size @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. diff --git a/src/ciphers/khazad.c b/src/ciphers/khazad.c index 207ea6f..4626923 100644 --- a/src/ciphers/khazad.c +++ b/src/ciphers/khazad.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" @@ -26,7 +26,9 @@ const struct ltc_cipher_descriptor khazad_desc = { &khazad_ecb_encrypt, &khazad_ecb_decrypt, &khazad_test, - &khazad_keysize + &khazad_done, + &khazad_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL }; #define R 8 @@ -819,6 +821,13 @@ int khazad_test(void) #endif } +/** Terminate the context + @param skey The scheduled key +*/ +void khazad_done(symmetric_key *skey) +{ +} + /** Gets suitable key size @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. diff --git a/src/ciphers/noekeon.c b/src/ciphers/noekeon.c index 0e31fdb..194cdbe 100644 --- a/src/ciphers/noekeon.c +++ b/src/ciphers/noekeon.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ /** @file noekeon.c @@ -25,7 +25,9 @@ const struct ltc_cipher_descriptor noekeon_desc = &noekeon_ecb_encrypt, &noekeon_ecb_decrypt, &noekeon_test, - &noekeon_keysize + &noekeon_done, + &noekeon_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL }; static const ulong32 RC[] = { @@ -263,6 +265,13 @@ int noekeon_test(void) #endif } +/** Terminate the context + @param skey The scheduled key +*/ +void noekeon_done(symmetric_key *skey) +{ +} + /** Gets suitable key size @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. diff --git a/src/ciphers/rc2.c b/src/ciphers/rc2.c index 68e53ea..6382941 100644 --- a/src/ciphers/rc2.c +++ b/src/ciphers/rc2.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ /**********************************************************************\ * To commemorate the 1996 RSA Data Security Conference, the following * @@ -34,7 +34,9 @@ const struct ltc_cipher_descriptor rc2_desc = { &rc2_ecb_encrypt, &rc2_ecb_decrypt, &rc2_test, - &rc2_keysize + &rc2_done, + &rc2_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL }; /* 256-entry permutation table, probably derived somehow from pi */ @@ -319,6 +321,13 @@ int rc2_test(void) #endif } +/** Terminate the context + @param skey The scheduled key +*/ +void rc2_done(symmetric_key *skey) +{ +} + /** Gets suitable key size @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. diff --git a/src/ciphers/rc5.c b/src/ciphers/rc5.c index 809be04..32f666f 100644 --- a/src/ciphers/rc5.c +++ b/src/ciphers/rc5.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ /** @@ -27,7 +27,9 @@ const struct ltc_cipher_descriptor rc5_desc = &rc5_ecb_encrypt, &rc5_ecb_decrypt, &rc5_test, - &rc5_keysize + &rc5_done, + &rc5_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL }; static const ulong32 stab[50] = { @@ -279,6 +281,13 @@ int rc5_test(void) #endif } +/** Terminate the context + @param skey The scheduled key +*/ +void rc5_done(symmetric_key *skey) +{ +} + /** Gets suitable key size @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. diff --git a/src/ciphers/rc6.c b/src/ciphers/rc6.c index 8ec389a..996c015 100644 --- a/src/ciphers/rc6.c +++ b/src/ciphers/rc6.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ /** @@ -26,7 +26,9 @@ const struct ltc_cipher_descriptor rc6_desc = &rc6_ecb_encrypt, &rc6_ecb_decrypt, &rc6_test, - &rc6_keysize + &rc6_done, + &rc6_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL }; static const ulong32 stab[44] = { @@ -309,6 +311,13 @@ int rc6_test(void) #endif } +/** Terminate the context + @param skey The scheduled key +*/ +void rc6_done(symmetric_key *skey) +{ +} + /** Gets suitable key size @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. diff --git a/src/ciphers/safer/safer.c b/src/ciphers/safer/safer.c index 491bf2b..e6e073a 100644 --- a/src/ciphers/safer/safer.c +++ b/src/ciphers/safer/safer.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ /******************************************************************************* @@ -40,7 +40,9 @@ const struct ltc_cipher_descriptor &safer_ecb_encrypt, &safer_ecb_decrypt, &safer_k64_test, - &safer_64_keysize + &safer_done, + &safer_64_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL }, safer_sk64_desc = { @@ -50,7 +52,9 @@ const struct ltc_cipher_descriptor &safer_ecb_encrypt, &safer_ecb_decrypt, &safer_sk64_test, - &safer_64_keysize + &safer_done, + &safer_64_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL }, safer_k128_desc = { @@ -60,7 +64,9 @@ const struct ltc_cipher_descriptor &safer_ecb_encrypt, &safer_ecb_decrypt, &safer_sk128_test, - &safer_128_keysize + &safer_done, + &safer_128_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL }, safer_sk128_desc = { @@ -70,11 +76,13 @@ const struct ltc_cipher_descriptor &safer_ecb_encrypt, &safer_ecb_decrypt, &safer_sk128_test, - &safer_128_keysize + &safer_done, + &safer_128_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL }; /******************* Constants ************************************************/ -// #define TAB_LEN 256 +/* #define TAB_LEN 256 */ /******************* Assertions ***********************************************/ @@ -428,6 +436,13 @@ int safer_sk64_test(void) #endif } +/** Terminate the context + @param skey The scheduled key +*/ +void safer_done(symmetric_key *skey) +{ +} + int safer_sk128_test(void) { #ifndef LTC_TEST diff --git a/src/ciphers/safer/safer_tab.c b/src/ciphers/safer/safer_tab.c index 5d1c31e..f63ba6c 100644 --- a/src/ciphers/safer/safer_tab.c +++ b/src/ciphers/safer/safer_tab.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ /** diff --git a/src/ciphers/safer/saferp.c b/src/ciphers/safer/saferp.c index 1d982b3..17112f4 100644 --- a/src/ciphers/safer/saferp.c +++ b/src/ciphers/safer/saferp.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ /** @@ -26,7 +26,9 @@ const struct ltc_cipher_descriptor saferp_desc = &saferp_ecb_encrypt, &saferp_ecb_decrypt, &saferp_test, - &saferp_keysize + &saferp_done, + &saferp_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL }; /* ROUND(b,i) @@ -516,6 +518,13 @@ int saferp_test(void) #endif } +/** Terminate the context + @param skey The scheduled key +*/ +void saferp_done(symmetric_key *skey) +{ +} + /** Gets suitable key size @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. diff --git a/src/ciphers/skipjack.c b/src/ciphers/skipjack.c index acc1d72..e2431af 100644 --- a/src/ciphers/skipjack.c +++ b/src/ciphers/skipjack.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ /** @@ -26,7 +26,9 @@ const struct ltc_cipher_descriptor skipjack_desc = &skipjack_ecb_encrypt, &skipjack_ecb_decrypt, &skipjack_test, - &skipjack_keysize + &skipjack_done, + &skipjack_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL }; static const unsigned char sbox[256] = { @@ -303,6 +305,13 @@ int skipjack_test(void) #endif } +/** Terminate the context + @param skey The scheduled key +*/ +void skipjack_done(symmetric_key *skey) +{ +} + /** Gets suitable key size @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. diff --git a/src/ciphers/twofish/twofish.c b/src/ciphers/twofish/twofish.c index cae0969..7dbe9b7 100644 --- a/src/ciphers/twofish/twofish.c +++ b/src/ciphers/twofish/twofish.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ /** @@ -33,7 +33,9 @@ const struct ltc_cipher_descriptor twofish_desc = &twofish_ecb_encrypt, &twofish_ecb_decrypt, &twofish_test, - &twofish_keysize + &twofish_done, + &twofish_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL }; /* the two polynomials */ @@ -665,6 +667,13 @@ int twofish_test(void) #endif } +/** Terminate the context + @param skey The scheduled key +*/ +void twofish_done(symmetric_key *skey) +{ +} + /** Gets suitable key size @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. diff --git a/src/ciphers/twofish/twofish_tab.c b/src/ciphers/twofish/twofish_tab.c index a7cfd80..0bffade 100644 --- a/src/ciphers/twofish/twofish_tab.c +++ b/src/ciphers/twofish/twofish_tab.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ /** diff --git a/src/ciphers/xtea.c b/src/ciphers/xtea.c index 42cc81d..98546df 100644 --- a/src/ciphers/xtea.c +++ b/src/ciphers/xtea.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ /** @@ -26,7 +26,9 @@ const struct ltc_cipher_descriptor xtea_desc = &xtea_ecb_encrypt, &xtea_ecb_decrypt, &xtea_test, - &xtea_keysize + &xtea_done, + &xtea_keysize, + NULL, NULL, NULL, NULL, NULL, NULL, NULL }; int xtea_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) @@ -172,6 +174,13 @@ int xtea_test(void) #endif } +/** Terminate the context + @param skey The scheduled key +*/ +void xtea_done(symmetric_key *skey) +{ +} + /** Gets suitable key size @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. diff --git a/src/encauth/ccm/ccm_memory.c b/src/encauth/ccm/ccm_memory.c new file mode 100644 index 0000000..34a254d --- /dev/null +++ b/src/encauth/ccm/ccm_memory.c @@ -0,0 +1,306 @@ +/* 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@gmail.com, http://libtomcrypt.org + */ +#include "tomcrypt.h" + +/** + @file ccm_memory.c + CCM support, process a block of memory, Tom St Denis +*/ + +#ifdef CCM_MODE + +/** + CCM encrypt/decrypt and produce an authentication tag + @param cipher The index of the cipher desired + @param key The secret key to use + @param keylen The length of the secret key (octets) + @param nonce The session nonce [use once] + @param noncelen The length of the nonce + @param header The header for the session + @param headerlen The length of the header (octets) + @param pt [out] The plaintext + @param ptlen The length of the plaintext (octets) + @param ct [out] The ciphertext + @param tag [out] The destination tag + @param taglen [in/out] The max size and resulting size of the authentication tag + @param direction Encrypt or Decrypt direction (0 or 1) + @return CRYPT_OK if successful +*/ +int ccm_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *header, unsigned long headerlen, + unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, unsigned long *taglen, + int direction) +{ + unsigned char PAD[16], ctr[16], CTRPAD[16], b; + symmetric_key *skey; + int err; + unsigned long len, L, x, y, z, CTRlen; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(nonce != NULL); + if (headerlen > 0) { + LTC_ARGCHK(header != NULL); + } + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(tag != NULL); + LTC_ARGCHK(taglen != NULL); + +#ifdef LTC_FAST + if (16 % sizeof(LTC_FAST_TYPE)) { + return CRYPT_INVALID_ARG; + } +#endif + + /* check cipher input */ + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + if (cipher_descriptor[cipher].block_length != 16) { + return CRYPT_INVALID_CIPHER; + } + + /* make sure the taglen is even and <= 16 */ + *taglen &= ~1; + if (*taglen > 16) { + *taglen = 16; + } + + /* can't use < 4 */ + if (*taglen < 4) { + return CRYPT_INVALID_ARG; + } + + /* is there an accelerator? */ + if (cipher_descriptor[cipher].accel_ccm_memory != NULL) { + cipher_descriptor[cipher].accel_ccm_memory( + key, keylen, + nonce, noncelen, + header, headerlen, + pt, ptlen, + ct, + tag, taglen, + direction); + return CRYPT_OK; + } + + /* let's get the L value */ + len = ptlen; + L = 0; + while (len) { + ++L; + len >>= 8; + } + if (L <= 1) { + L = 2; + } + + /* increase L to match the nonce len */ + noncelen = (noncelen > 13) ? 13 : noncelen; + if ((15 - noncelen) > L) { + L = 15 - noncelen; + } + + /* allocate mem for the symmetric key */ + skey = XMALLOC(sizeof(*skey)); + if (skey == NULL) { + return CRYPT_MEM; + } + + /* initialize the cipher */ + if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, skey)) != CRYPT_OK) { + XFREE(skey); + return err; + } + + /* form B_0 == flags | Nonce N | l(m) */ + x = 0; + PAD[x++] = ((headerlen > 0) ? (1<<6) : 0) | + (((*taglen - 2)>>1)<<3) | + (L-1); + + /* nonce */ + for (y = 0; y < (16 - (L + 1)); y++) { + PAD[x++] = nonce[y]; + } + + /* store len */ + len = ptlen; + + /* shift len so the upper bytes of len are the contents of the length */ + for (y = L; y < 4; y++) { + len <<= 8; + } + + /* store l(m) (only store 32-bits) */ + for (y = 0; L > 4 && (L-y)>4; y++) { + PAD[x++] = 0; + } + for (; y < L; y++) { + PAD[x++] = (len >> 24) & 255; + len <<= 8; + } + + /* encrypt PAD */ + cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey); + + /* handle header */ + if (headerlen > 0) { + x = 0; + + /* store length */ + if (headerlen < ((1UL<<16) - (1UL<<8))) { + PAD[x++] ^= (headerlen>>8) & 255; + PAD[x++] ^= headerlen & 255; + } else { + PAD[x++] ^= 0xFF; + PAD[x++] ^= 0xFE; + PAD[x++] ^= (headerlen>>24) & 255; + PAD[x++] ^= (headerlen>>16) & 255; + PAD[x++] ^= (headerlen>>8) & 255; + PAD[x++] ^= headerlen & 255; + } + + /* now add the data */ + for (y = 0; y < headerlen; y++) { + if (x == 16) { + /* full block so let's encrypt it */ + cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey); + x = 0; + } + PAD[x++] ^= header[y]; + } + + /* remainder? */ + if (x != 0) { + cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey); + } + } + + /* setup the ctr counter */ + x = 0; + + /* flags */ + ctr[x++] = L-1; + + /* nonce */ + for (y = 0; y < (16 - (L+1)); ++y) { + ctr[x++] = nonce[y]; + } + /* offset */ + while (x < 16) { + ctr[x++] = 0; + } + + x = 0; + CTRlen = 16; + + /* now handle the PT */ + if (ptlen > 0) { + y = 0; +#ifdef LTC_FAST + if (ptlen & ~15) { + if (direction == CCM_ENCRYPT) { + for (; y < (ptlen & ~15); y += 16) { + /* increment the ctr? */ + for (z = 15; z > 15-L; z--) { + ctr[z] = (ctr[z] + 1) & 255; + if (ctr[z]) break; + } + cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey); + + /* xor the PT against the pad first */ + for (z = 0; z < 16; z += sizeof(LTC_FAST_TYPE)) { + *((LTC_FAST_TYPE*)(&PAD[z])) ^= *((LTC_FAST_TYPE*)(&pt[y+z])); + *((LTC_FAST_TYPE*)(&ct[y+z])) = *((LTC_FAST_TYPE*)(&pt[y+z])) ^ *((LTC_FAST_TYPE*)(&CTRPAD[z])); + } + cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey); + } + } else { + for (; y < (ptlen & ~15); y += 16) { + /* increment the ctr? */ + for (z = 15; z > 15-L; z--) { + ctr[z] = (ctr[z] + 1) & 255; + if (ctr[z]) break; + } + cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey); + + /* xor the PT against the pad last */ + for (z = 0; z < 16; z += sizeof(LTC_FAST_TYPE)) { + *((LTC_FAST_TYPE*)(&pt[y+z])) = *((LTC_FAST_TYPE*)(&ct[y+z])) ^ *((LTC_FAST_TYPE*)(&CTRPAD[z])); + *((LTC_FAST_TYPE*)(&PAD[z])) ^= *((LTC_FAST_TYPE*)(&pt[y+z])); + } + cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey); + } + } + } +#endif + + for (; y < ptlen; y++) { + /* increment the ctr? */ + if (CTRlen == 16) { + for (z = 15; z > 15-L; z--) { + ctr[z] = (ctr[z] + 1) & 255; + if (ctr[z]) break; + } + cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey); + CTRlen = 0; + } + + /* if we encrypt we add the bytes to the MAC first */ + if (direction == CCM_ENCRYPT) { + b = pt[y]; + ct[y] = b ^ CTRPAD[CTRlen++]; + } else { + b = ct[y] ^ CTRPAD[CTRlen++]; + pt[y] = b; + } + + if (x == 16) { + cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey); + x = 0; + } + PAD[x++] ^= b; + } + + if (x != 0) { + cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey); + } + } + + /* setup CTR for the TAG */ + ctr[14] = ctr[15] = 0x00; + cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey); + cipher_descriptor[cipher].done(skey); + + /* store the TAG */ + for (x = 0; x < 16 && x < *taglen; x++) { + tag[x] = PAD[x] ^ CTRPAD[x]; + } + *taglen = x; + +#ifdef LTC_CLEAN_STACK + zeromem(skey, sizeof(*skey)); + zeromem(B, sizeof(B)); + zeromem(PAD, sizeof(PAD)); + zeromem(CTRPAD, sizeof(CTRPAD)); +#endif + + XFREE(skey); + + return CRYPT_OK; +} + +#endif diff --git a/src/encauth/ccm/ccm_test.c b/src/encauth/ccm/ccm_test.c new file mode 100644 index 0000000..ee78523 --- /dev/null +++ b/src/encauth/ccm/ccm_test.c @@ -0,0 +1,170 @@ +/* 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@gmail.com, http://libtomcrypt.org + */ +#include "tomcrypt.h" + +/** + @file ccm_test.c + CCM support, process a block of memory, Tom St Denis +*/ + +#ifdef CCM_MODE + +int ccm_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + static const struct { + unsigned char key[16]; + unsigned char nonce[16]; + int noncelen; + unsigned char header[64]; + int headerlen; + unsigned char pt[64]; + int ptlen; + unsigned char ct[64]; + unsigned char tag[16]; + int taglen; + } tests[] = { + +/* 13 byte nonce, 8 byte auth, 23 byte pt */ +{ + { 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, + 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF }, + { 0x00, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 0xA0, + 0xA1, 0xA2, 0xA3, 0xA4, 0xA5 }, + 13, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }, + 8, + { 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E }, + 23, + { 0x58, 0x8C, 0x97, 0x9A, 0x61, 0xC6, 0x63, 0xD2, + 0xF0, 0x66, 0xD0, 0xC2, 0xC0, 0xF9, 0x89, 0x80, + 0x6D, 0x5F, 0x6B, 0x61, 0xDA, 0xC3, 0x84 }, + { 0x17, 0xe8, 0xd1, 0x2c, 0xfd, 0xf9, 0x26, 0xe0 }, + 8 +}, + +/* 13 byte nonce, 12 byte header, 19 byte pt */ +{ + { 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, + 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF }, + { 0x00, 0x00, 0x00, 0x06, 0x05, 0x04, 0x03, 0xA0, + 0xA1, 0xA2, 0xA3, 0xA4, 0xA5 }, + 13, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B }, + 12, + { 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, + 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, + 0x1C, 0x1D, 0x1E }, + 19, + { 0xA2, 0x8C, 0x68, 0x65, 0x93, 0x9A, 0x9A, 0x79, + 0xFA, 0xAA, 0x5C, 0x4C, 0x2A, 0x9D, 0x4A, 0x91, + 0xCD, 0xAC, 0x8C }, + { 0x96, 0xC8, 0x61, 0xB9, 0xC9, 0xE6, 0x1E, 0xF1 }, + 8 +}, + +/* supplied by Brian Gladman */ +{ + { 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f }, + { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 }, + 7, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }, + 8, + { 0x20, 0x21, 0x22, 0x23 }, + 4, + { 0x71, 0x62, 0x01, 0x5b }, + { 0x4d, 0xac, 0x25, 0x5d }, + 4 +}, + +{ + { 0xc9, 0x7c, 0x1f, 0x67, 0xce, 0x37, 0x11, 0x85, + 0x51, 0x4a, 0x8a, 0x19, 0xf2, 0xbd, 0xd5, 0x2f }, + { 0x00, 0x50, 0x30, 0xf1, 0x84, 0x44, 0x08, 0xb5, + 0x03, 0x97, 0x76, 0xe7, 0x0c }, + 13, + { 0x08, 0x40, 0x0f, 0xd2, 0xe1, 0x28, 0xa5, 0x7c, + 0x50, 0x30, 0xf1, 0x84, 0x44, 0x08, 0xab, 0xae, + 0xa5, 0xb8, 0xfc, 0xba, 0x00, 0x00 }, + 22, + { 0xf8, 0xba, 0x1a, 0x55, 0xd0, 0x2f, 0x85, 0xae, + 0x96, 0x7b, 0xb6, 0x2f, 0xb6, 0xcd, 0xa8, 0xeb, + 0x7e, 0x78, 0xa0, 0x50 }, + 20, + { 0xf3, 0xd0, 0xa2, 0xfe, 0x9a, 0x3d, 0xbf, 0x23, + 0x42, 0xa6, 0x43, 0xe4, 0x32, 0x46, 0xe8, 0x0c, + 0x3c, 0x04, 0xd0, 0x19 }, + { 0x78, 0x45, 0xce, 0x0b, 0x16, 0xf9, 0x76, 0x23 }, + 8 +}, + +}; + unsigned long taglen, x; + unsigned char buf[64], buf2[64], tag2[16], tag[16]; + int err, idx; + + idx = find_cipher("aes"); + if (idx == -1) { + idx = find_cipher("rijndael"); + if (idx == -1) { + return CRYPT_NOP; + } + } + + for (x = 0; x < (sizeof(tests)/sizeof(tests[0])); x++) { + taglen = tests[x].taglen; + if ((err = ccm_memory(idx, + tests[x].key, 16, + tests[x].nonce, tests[x].noncelen, + tests[x].header, tests[x].headerlen, + (unsigned char*)tests[x].pt, tests[x].ptlen, + buf, + tag, &taglen, 0)) != CRYPT_OK) { + return err; + } + + if (memcmp(buf, tests[x].ct, tests[x].ptlen)) { + return CRYPT_FAIL_TESTVECTOR; + } + if (memcmp(tag, tests[x].tag, tests[x].taglen)) { + return CRYPT_FAIL_TESTVECTOR; + } + + if ((err = ccm_memory(idx, + tests[x].key, 16, + tests[x].nonce, tests[x].noncelen, + tests[x].header, tests[x].headerlen, + buf2, tests[x].ptlen, + buf, + tag2, &taglen, 1 )) != CRYPT_OK) { + return err; + } + + if (memcmp(buf2, tests[x].pt, tests[x].ptlen)) { + return CRYPT_FAIL_TESTVECTOR; + } + if (memcmp(tag2, tests[x].tag, tests[x].taglen)) { + return CRYPT_FAIL_TESTVECTOR; + } + + + } + return CRYPT_OK; +#endif +} + +#endif diff --git a/src/encauth/eax/eax_addheader.c b/src/encauth/eax/eax_addheader.c index 1ec2300..3004025 100644 --- a/src/encauth/eax/eax_addheader.c +++ b/src/encauth/eax/eax_addheader.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ /** @file eax_addheader.c diff --git a/src/encauth/eax/eax_decrypt.c b/src/encauth/eax/eax_decrypt.c index 4217254..8711d2d 100644 --- a/src/encauth/eax/eax_decrypt.c +++ b/src/encauth/eax/eax_decrypt.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ /** diff --git a/src/encauth/eax/eax_decrypt_verify_memory.c b/src/encauth/eax/eax_decrypt_verify_memory.c index 1929e80..3fcab46 100644 --- a/src/encauth/eax/eax_decrypt_verify_memory.c +++ b/src/encauth/eax/eax_decrypt_verify_memory.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ /** diff --git a/src/encauth/eax/eax_done.c b/src/encauth/eax/eax_done.c index 73342b8..1d43651 100644 --- a/src/encauth/eax/eax_done.c +++ b/src/encauth/eax/eax_done.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ /** @@ -62,6 +62,11 @@ int eax_done(eax_state *eax, unsigned char *tag, unsigned long *taglen) goto LBL_ERR; } + /* terminate the CTR chain */ + if ((err = ctr_done(&eax->ctr)) != CRYPT_OK) { + goto LBL_ERR; + } + /* compute N xor H xor C */ for (x = 0; x < len && x < *taglen; x++) { tag[x] = eax->N[x] ^ headermac[x] ^ ctmac[x]; diff --git a/src/encauth/eax/eax_encrypt.c b/src/encauth/eax/eax_encrypt.c index 55b4f76..da23a8c 100644 --- a/src/encauth/eax/eax_encrypt.c +++ b/src/encauth/eax/eax_encrypt.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ /** diff --git a/src/encauth/eax/eax_encrypt_authenticate_memory.c b/src/encauth/eax/eax_encrypt_authenticate_memory.c index 2a09f53..8a601cf 100644 --- a/src/encauth/eax/eax_encrypt_authenticate_memory.c +++ b/src/encauth/eax/eax_encrypt_authenticate_memory.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ /** diff --git a/src/encauth/eax/eax_init.c b/src/encauth/eax/eax_init.c index 58d8f8d..5a20db0 100644 --- a/src/encauth/eax/eax_init.c +++ b/src/encauth/eax/eax_init.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ /** diff --git a/src/encauth/eax/eax_test.c b/src/encauth/eax/eax_test.c index 7a1ec24..777dea1 100644 --- a/src/encauth/eax/eax_test.c +++ b/src/encauth/eax/eax_test.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ /** diff --git a/src/encauth/gcm/gcm_add_aad.c b/src/encauth/gcm/gcm_add_aad.c new file mode 100644 index 0000000..7354e3a --- /dev/null +++ b/src/encauth/gcm/gcm_add_aad.c @@ -0,0 +1,120 @@ +/* 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@gmail.com, http://libtomcrypt.org + */ + +/** + @file gcm_add_aad.c + GCM implementation, Add AAD data to the stream, by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef GCM_MODE + +/** + Add AAD to the GCM state + @param gcm The GCM state + @param adata The additional authentication data to add to the GCM state + @param adatalen The length of the AAD data. + @return CRYPT_OK on success + */ +int gcm_add_aad(gcm_state *gcm, + const unsigned char *adata, unsigned long adatalen) +{ + unsigned long x, y; + int err; + + LTC_ARGCHK(gcm != NULL); + if (adatalen > 0) { + LTC_ARGCHK(adata != NULL); + } + + if (gcm->buflen > 16 || gcm->buflen < 0) { + return CRYPT_INVALID_ARG; + } + + if ((err = cipher_is_valid(gcm->cipher)) != CRYPT_OK) { + return err; + } + + /* in IV mode? */ + if (gcm->mode == GCM_MODE_IV) { + /* let's process the IV */ + if (gcm->ivmode || gcm->buflen != 12) { + for (x = 0; x < (unsigned long)gcm->buflen; x++) { + gcm->X[x] ^= gcm->buf[x]; + } + if (gcm->buflen) { + gcm->totlen += gcm->buflen * CONST64(8); + gcm_mult_h(gcm, gcm->X); + } + + /* mix in the length */ + zeromem(gcm->buf, 8); + STORE64H(gcm->totlen, gcm->buf+8); + for (x = 0; x < 16; x++) { + gcm->X[x] ^= gcm->buf[x]; + } + gcm_mult_h(gcm, gcm->X); + + /* copy counter out */ + XMEMCPY(gcm->Y, gcm->X, 16); + zeromem(gcm->X, 16); + } else { + XMEMCPY(gcm->Y, gcm->buf, 12); + gcm->Y[12] = 0; + gcm->Y[13] = 0; + gcm->Y[14] = 0; + gcm->Y[15] = 1; + } + XMEMCPY(gcm->Y_0, gcm->Y, 16); + zeromem(gcm->buf, 16); + gcm->buflen = 0; + gcm->totlen = 0; + gcm->mode = GCM_MODE_AAD; + } + + if (gcm->mode != GCM_MODE_AAD || gcm->buflen >= 16) { + return CRYPT_INVALID_ARG; + } + + x = 0; +#ifdef LTC_FAST + if (gcm->buflen == 0) { + for (x = 0; x < (adatalen & ~15); x += 16) { + for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) { + *((LTC_FAST_TYPE*)(&gcm->X[y])) ^= *((LTC_FAST_TYPE*)(&adata[x + y])); + } + gcm_mult_h(gcm, gcm->X); + gcm->totlen += 128; + } + adata += x; + } +#endif + + + /* start adding AAD data to the state */ + for (; x < adatalen; x++) { + gcm->buf[gcm->buflen++] = *adata++; + + if (gcm->buflen == 16) { + /* GF mult it */ + for (y = 0; y < 16; y++) { + gcm->X[y] ^= gcm->buf[y]; + } + gcm_mult_h(gcm, gcm->X); + gcm->buflen = 0; + gcm->totlen += 128; + } + } + + return CRYPT_OK; +} +#endif + diff --git a/src/encauth/gcm/gcm_add_iv.c b/src/encauth/gcm/gcm_add_iv.c new file mode 100644 index 0000000..7faf4c0 --- /dev/null +++ b/src/encauth/gcm/gcm_add_iv.c @@ -0,0 +1,90 @@ +/* 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@gmail.com, http://libtomcrypt.org + */ + +/** + @file gcm_add_iv.c + GCM implementation, add IV data to the state, by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef GCM_MODE + +/** + Add IV data to the GCM state + @param gcm The GCM state + @param IV The initial value data to add + @param IVlen The length of the IV + @return CRYPT_OK on success + */ +int gcm_add_iv(gcm_state *gcm, + const unsigned char *IV, unsigned long IVlen) +{ + unsigned long x, y; + int err; + + LTC_ARGCHK(gcm != NULL); + if (IVlen > 0) { + LTC_ARGCHK(IV != NULL); + } + + /* must be in IV mode */ + if (gcm->mode != GCM_MODE_IV) { + return CRYPT_INVALID_ARG; + } + + if (gcm->buflen >= 16 || gcm->buflen < 0) { + return CRYPT_INVALID_ARG; + } + + if ((err = cipher_is_valid(gcm->cipher)) != CRYPT_OK) { + return err; + } + + + /* trip the ivmode flag */ + if (IVlen + gcm->buflen > 12) { + gcm->ivmode |= 1; + } + + x = 0; +#ifdef LTC_FAST + if (gcm->buflen == 0) { + for (x = 0; x < (IVlen & ~15); x += 16) { + for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) { + *((LTC_FAST_TYPE*)(&gcm->X[y])) ^= *((LTC_FAST_TYPE*)(&IV[x + y])); + } + gcm_mult_h(gcm, gcm->X); + gcm->totlen += 128; + } + IV += x; + } +#endif + + /* start adding IV data to the state */ + for (; x < IVlen; x++) { + gcm->buf[gcm->buflen++] = *IV++; + + if (gcm->buflen == 16) { + /* GF mult it */ + for (y = 0; y < 16; y++) { + gcm->X[y] ^= gcm->buf[y]; + } + gcm_mult_h(gcm, gcm->X); + gcm->buflen = 0; + gcm->totlen += 128; + } + } + + return CRYPT_OK; +} + +#endif + diff --git a/src/encauth/gcm/gcm_done.c b/src/encauth/gcm/gcm_done.c new file mode 100644 index 0000000..49ca638 --- /dev/null +++ b/src/encauth/gcm/gcm_done.c @@ -0,0 +1,80 @@ +/* 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@gmail.com, http://libtomcrypt.org + */ + +/** + @file gcm_done.c + GCM implementation, Terminate the stream, by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef GCM_MODE + +/** + Terminate a GCM stream + @param gcm The GCM state + @param tag [out] The destination for the MAC tag + @param taglen [in/out] The length of the MAC tag + @return CRYPT_OK on success + */ +int gcm_done(gcm_state *gcm, + unsigned char *tag, unsigned long *taglen) +{ + unsigned long x; + int err; + + LTC_ARGCHK(gcm != NULL); + LTC_ARGCHK(tag != NULL); + LTC_ARGCHK(taglen != NULL); + + if (gcm->buflen > 16 || gcm->buflen < 0) { + return CRYPT_INVALID_ARG; + } + + if ((err = cipher_is_valid(gcm->cipher)) != CRYPT_OK) { + return err; + } + + + if (gcm->mode != GCM_MODE_TEXT) { + return CRYPT_INVALID_ARG; + } + + /* handle remaining ciphertext */ + if (gcm->buflen) { + for (x = 0; x < (unsigned long)gcm->buflen; x++) { + gcm->X[x] ^= gcm->buf[x]; + } + gcm->pttotlen += gcm->buflen * CONST64(8); + gcm_mult_h(gcm, gcm->X); + } + + /* length */ + STORE64H(gcm->totlen, gcm->buf); + STORE64H(gcm->pttotlen, gcm->buf+8); + for (x = 0; x < 16; x++) { + gcm->X[x] ^= gcm->buf[x]; + } + gcm_mult_h(gcm, gcm->X); + + /* encrypt original counter */ + cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y_0, gcm->buf, &gcm->K); + for (x = 0; x < 16 && x < *taglen; x++) { + tag[x] = gcm->buf[x] ^ gcm->X[x]; + } + *taglen = x; + + cipher_descriptor[gcm->cipher].done(&gcm->K); + + return CRYPT_OK; +} + +#endif + diff --git a/src/encauth/gcm/gcm_gf_mult.c b/src/encauth/gcm/gcm_gf_mult.c new file mode 100644 index 0000000..a870c91 --- /dev/null +++ b/src/encauth/gcm/gcm_gf_mult.c @@ -0,0 +1,89 @@ +/* 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@gmail.com, http://libtomcrypt.org + */ + +/** + @file gcm_gf_mult.c + GCM implementation, initialize state, by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef GCM_MODE + +/* right shift */ +static void gcm_rightshift(unsigned char *a) +{ + int x; + for (x = 15; x > 0; x--) { + a[x] = (a[x]>>1) | ((a[x-1]<<7)&0x80); + } + a[0] >>= 1; +} + +/* c = b*a */ +static const unsigned char mask[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }; +static const unsigned char poly[] = { 0x00, 0xE1 }; + +/** + GCM GF multiplier (internal use only) + @param a First value + @param b Second value + @param c Destination for a * b + */ +void gcm_gf_mult(const unsigned char *a, const unsigned char *b, unsigned char *c) +{ + unsigned char Z[16], V[16]; + unsigned x, y, z; + + zeromem(Z, 16); + XMEMCPY(V, a, 16); + for (x = 0; x < 128; x++) { + if (b[x>>3] & mask[x&7]) { + for (y = 0; y < 16; y++) { + Z[y] ^= V[y]; + } + } + z = V[15] & 0x01; + gcm_rightshift(V); + V[0] ^= poly[z]; + } + XMEMCPY(c, Z, 16); +} + +/** + GCM multiply by H + @param gcm The GCM state which holds the H value + @param I The value to multiply H by + */ +void gcm_mult_h(gcm_state *gcm, unsigned char *I) +{ + unsigned char T[16]; +#ifdef GCM_TABLES + int x, y; + XMEMCPY(T, &gcm->PC[0][I[0]][0], 16); + for (x = 1; x < 16; x++) { +#ifdef LTC_FAST + for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) { + *((LTC_FAST_TYPE *)(T + y)) ^= *((LTC_FAST_TYPE *)(&gcm->PC[x][I[x]][y])); + } +#else + for (y = 0; y < 16; y++) { + T[y] ^= gcm->PC[x][I[x]][y]; + } +#endif + } +#else + gcm_gf_mult(gcm->H, I, T); +#endif + XMEMCPY(I, T, 16); +} + + +#endif diff --git a/src/encauth/gcm/gcm_init.c b/src/encauth/gcm/gcm_init.c new file mode 100644 index 0000000..35a5ab8 --- /dev/null +++ b/src/encauth/gcm/gcm_init.c @@ -0,0 +1,88 @@ +/* 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@gmail.com, http://libtomcrypt.org + */ + +/** + @file gcm_init.c + GCM implementation, initialize state, by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef GCM_MODE + +/** + Initialize a GCM state + @param gcm The GCM state to initialize + @param cipher The index of the cipher to use + @param key The secret key + @param keylen The length of the secret key + @return CRYPT_OK on success + */ +int gcm_init(gcm_state *gcm, int cipher, + const unsigned char *key, int keylen) +{ + int err; + unsigned char B[16]; +#ifdef GCM_TABLES + int x, y; +#endif + + LTC_ARGCHK(gcm != NULL); + LTC_ARGCHK(key != NULL); + +#ifdef LTC_FAST + if (16 % sizeof(LTC_FAST_TYPE)) { + return CRYPT_INVALID_ARG; + } +#endif + + /* is cipher valid? */ + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + if (cipher_descriptor[cipher].block_length != 16) { + return CRYPT_INVALID_CIPHER; + } + + /* schedule key */ + if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &gcm->K)) != CRYPT_OK) { + return err; + } + + /* H = E(0) */ + zeromem(B, 16); + cipher_descriptor[cipher].ecb_encrypt(B, gcm->H, &gcm->K); + + /* setup state */ + zeromem(gcm->buf, sizeof(gcm->buf)); + zeromem(gcm->X, sizeof(gcm->X)); + gcm->cipher = cipher; + gcm->mode = GCM_MODE_IV; + gcm->ivmode = 0; + gcm->buflen = 0; + gcm->totlen = 0; + gcm->pttotlen = 0; + +#ifdef GCM_TABLES + /* setup tables */ + zeromem(B, 16); + for (x = 0; x < 16; x++) { + for (y = 0; y < 256; y++) { + B[x] = y; + gcm_gf_mult(gcm->H, B, &gcm->PC[x][y][0]); + } + B[x] = 0; + } +#endif + + return CRYPT_OK; +} + +#endif diff --git a/src/encauth/gcm/gcm_memory.c b/src/encauth/gcm/gcm_memory.c new file mode 100644 index 0000000..e062413 --- /dev/null +++ b/src/encauth/gcm/gcm_memory.c @@ -0,0 +1,89 @@ +/* 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@gmail.com, http://libtomcrypt.org + */ + +/** + @file gcm_memory.c + GCM implementation, process a packet, by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef GCM_MODE + +/** + Process an entire GCM packet in one call. + @param cipher Index of cipher to use + @param key The secret key + @param keylen The length of the secret key + @param IV The initial vector + @param IVlen The length of the initial vector + @param adata The additional authentication data (header) + @param adatalen The length of the adata + @param pt The plaintext + @param ptlen The length of the plaintext (ciphertext length is the same) + @param ct The ciphertext + @param tag [out] The MAC tag + @param taglen [in/out] The MAC tag length + @param direction Encrypt or Decrypt mode (GCM_ENCRYPT or GCM_DECRYPT) + @return CRYPT_OK on success + */ +int gcm_memory( int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *IV, unsigned long IVlen, + const unsigned char *adata, unsigned long adatalen, + unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, unsigned long *taglen, + int direction) +{ + gcm_state *gcm; + int err; + + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + + if (cipher_descriptor[cipher].accel_gcm_memory != NULL) { + cipher_descriptor[cipher].accel_gcm_memory + (key, keylen, + IV, IVlen, + adata, adatalen, + pt, ptlen, + ct, + tag, taglen, + direction); + return CRYPT_OK; + } + + + gcm = XMALLOC(sizeof(*gcm)); + if (gcm == NULL) { + return CRYPT_MEM; + } + + if ((err = gcm_init(gcm, cipher, key, keylen)) != CRYPT_OK) { + goto LTC_ERR; + } + if ((err = gcm_add_iv(gcm, IV, IVlen)) != CRYPT_OK) { + goto LTC_ERR; + } + if ((err = gcm_add_aad(gcm, adata, adatalen)) != CRYPT_OK) { + goto LTC_ERR; + } + if ((err = gcm_process(gcm, pt, ptlen, ct, direction)) != CRYPT_OK) { + goto LTC_ERR; + } + err = gcm_done(gcm, tag, taglen); +LTC_ERR: + XFREE(gcm); + return err; +} +#endif + diff --git a/src/encauth/gcm/gcm_process.c b/src/encauth/gcm/gcm_process.c new file mode 100644 index 0000000..15a9c07 --- /dev/null +++ b/src/encauth/gcm/gcm_process.c @@ -0,0 +1,147 @@ +/* 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@gmail.com, http://libtomcrypt.org + */ + +/** + @file gcm_process.c + GCM implementation, process message data, by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef GCM_MODE + +/** + Process plaintext/ciphertext through GCM + @param gcm The GCM state + @param pt The plaintext + @param ptlen The plaintext length (ciphertext length is the same) + @param ct The ciphertext + @param direction Encrypt or Decrypt mode (GCM_ENCRYPT or GCM_DECRYPT) + @return CRYPT_OK on success + */ +int gcm_process(gcm_state *gcm, + unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + int direction) +{ + unsigned long x, y; + unsigned char b; + int err; + + LTC_ARGCHK(gcm != NULL); + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); + + if (gcm->buflen > 16 || gcm->buflen < 0) { + return CRYPT_INVALID_ARG; + } + + if ((err = cipher_is_valid(gcm->cipher)) != CRYPT_OK) { + return err; + } + + /* in AAD mode? */ + if (gcm->mode == GCM_MODE_AAD) { + /* let's process the AAD */ + if (gcm->buflen) { + for (x = 0; x < (unsigned long)gcm->buflen; x++) { + gcm->X[x] ^= gcm->buf[x]; + } + gcm->totlen += gcm->buflen * CONST64(8); + gcm_mult_h(gcm, gcm->X); + } + + /* increment counter */ + for (y = 15; y >= 12; y--) { + if (++gcm->Y[y]) { break; } + } + /* encrypt the counter */ + cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K); + + gcm->buflen = 0; + gcm->mode = GCM_MODE_TEXT; + } + + if (gcm->mode != GCM_MODE_TEXT) { + return CRYPT_INVALID_ARG; + } + + x = 0; +#ifdef LTC_FAST + if (gcm->buflen == 0) { + if (direction == GCM_ENCRYPT) { + for (x = 0; x < (ptlen & ~15); x += 16) { + /* ctr encrypt */ + for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) { + *((LTC_FAST_TYPE*)(&ct[x + y])) = *((LTC_FAST_TYPE*)(&pt[x+y])) ^ *((LTC_FAST_TYPE*)(&gcm->buf[y])); + *((LTC_FAST_TYPE*)(&gcm->X[y])) ^= *((LTC_FAST_TYPE*)(&ct[x+y])); + } + /* GMAC it */ + gcm->pttotlen += 128; + gcm_mult_h(gcm, gcm->X); + /* increment counter */ + for (y = 15; y >= 12; y--) { + if (++gcm->Y[y]) { break; } + } + cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K); + } + } else { + for (x = 0; x < (ptlen & ~15); x += 16) { + /* ctr encrypt */ + for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) { + *((LTC_FAST_TYPE*)(&gcm->X[y])) ^= *((LTC_FAST_TYPE*)(&ct[x+y])); + *((LTC_FAST_TYPE*)(&pt[x + y])) = *((LTC_FAST_TYPE*)(&ct[x+y])) ^ *((LTC_FAST_TYPE*)(&gcm->buf[y])); + } + /* GMAC it */ + gcm->pttotlen += 128; + gcm_mult_h(gcm, gcm->X); + /* increment counter */ + for (y = 15; y >= 12; y--) { + if (++gcm->Y[y]) { break; } + } + cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K); + } + } + } +#endif + + /* process text */ + for (; x < ptlen; x++) { + if (gcm->buflen == 16) { + for (y = 0; y < 16; y++) { + gcm->X[y] ^= gcm->buf[y]; + } + gcm->pttotlen += 128; + gcm_mult_h(gcm, gcm->X); + + /* increment counter */ + for (y = 15; y >= 12; y--) { + if (++gcm->Y[y]) { break; } + } + cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K); + gcm->buflen = 0; + } + + if (direction == GCM_ENCRYPT) { + b = ct[x] = pt[x] ^ gcm->buf[gcm->buflen]; + } else { + b = ct[x]; + pt[x] = ct[x] ^ gcm->buf[gcm->buflen]; + } + gcm->buf[gcm->buflen++] = b; + } + + return CRYPT_OK; +} + + + +#endif + diff --git a/src/encauth/gcm/gcm_reset.c b/src/encauth/gcm/gcm_reset.c new file mode 100644 index 0000000..e73bf66 --- /dev/null +++ b/src/encauth/gcm/gcm_reset.c @@ -0,0 +1,40 @@ +/* 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@gmail.com, http://libtomcrypt.org + */ + +/** + @file gcm_reset.c + GCM implementation, reset a used state so it can accept IV data, by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef GCM_MODE + +/** + Reset a GCM state to as if you just called gcm_init(). This saves the initialization time. + @param gcm The GCM state to reset + @return CRYPT_OK on success +*/ +int gcm_reset(gcm_state *gcm) +{ + LTC_ARGCHK(gcm != NULL); + + zeromem(gcm->buf, sizeof(gcm->buf)); + zeromem(gcm->X, sizeof(gcm->X)); + gcm->mode = GCM_MODE_IV; + gcm->ivmode = 0; + gcm->buflen = 0; + gcm->totlen = 0; + gcm->pttotlen = 0; + + return CRYPT_OK; +} + +#endif diff --git a/src/encauth/gcm/gcm_test.c b/src/encauth/gcm/gcm_test.c new file mode 100644 index 0000000..7c20967 --- /dev/null +++ b/src/encauth/gcm/gcm_test.c @@ -0,0 +1,361 @@ +/* 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@gmail.com, http://libtomcrypt.org + */ + +/** + @file gcm_test.c + GCM implementation, testing, by Tom St Denis +*/ +#include "tomcrypt.h" + +#ifdef GCM_MODE + +/** + Test the GCM code + @return CRYPT_OK on success + */ +int gcm_test(void) +{ + static const struct { + unsigned char K[32]; + int keylen; + unsigned char P[64]; + unsigned long ptlen; + unsigned char A[64]; + unsigned long alen; + unsigned char IV[64]; + unsigned long IVlen; + unsigned char C[64]; + unsigned char T[16]; + } tests[] = { + +/* test case #1 */ +{ + /* key */ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + 16, + + /* plaintext */ + { 0 }, + 0, + + /* AAD data */ + { 0 }, + 0, + + /* IV */ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 }, + 12, + + /* ciphertext */ + { 0 }, + + /* tag */ + { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61, + 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a } +}, + +/* test case #2 */ +{ + /* key */ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + 16, + + /* PT */ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + 16, + + /* ADATA */ + { 0 }, + 0, + + /* IV */ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 }, + 12, + + /* CT */ + { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92, + 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 }, + + /* TAG */ + { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd, + 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf } +}, + +/* test case #3 */ +{ + /* key */ + { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, }, + 16, + + /* PT */ + { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, }, + 64, + + /* ADATA */ + { 0 }, + 0, + + /* IV */ + { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88, }, + 12, + + /* CT */ + { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, + 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, + 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, + 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, + 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, + 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, + 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, + 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85, }, + + /* TAG */ + { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6, + 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4, } +}, + +/* test case #4 */ +{ + /* key */ + { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, }, + 16, + + /* PT */ + { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, }, + 60, + + /* ADATA */ + { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xab, 0xad, 0xda, 0xd2, }, + 20, + + /* IV */ + { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88, }, + 12, + + /* CT */ + { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, + 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, + 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, + 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, + 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, + 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, + 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, + 0x3d, 0x58, 0xe0, 0x91, }, + + /* TAG */ + { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb, + 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47, } + +}, + +/* test case #5 */ +{ + /* key */ + { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, }, + 16, + + /* PT */ + { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, }, + 60, + + /* ADATA */ + { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xab, 0xad, 0xda, 0xd2, }, + 20, + + /* IV */ + { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, }, + 8, + + /* CT */ + { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a, + 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55, + 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8, + 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23, + 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2, + 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42, + 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07, + 0xc2, 0x3f, 0x45, 0x98, }, + + /* TAG */ + { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85, + 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb, } +}, + +/* test case #6 */ +{ + /* key */ + { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, }, + 16, + + /* PT */ + { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, }, + 60, + + /* ADATA */ + { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xab, 0xad, 0xda, 0xd2, }, + 20, + + /* IV */ + { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5, + 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa, + 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1, + 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28, + 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39, + 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54, + 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57, + 0xa6, 0x37, 0xb3, 0x9b, }, + 60, + + /* CT */ + { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6, + 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94, + 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8, + 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7, + 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90, + 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f, + 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03, + 0x4c, 0x34, 0xae, 0xe5, }, + + /* TAG */ + { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa, + 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50, } +} + +/* rest of test cases are the same except AES key size changes... ignored... */ +}; + int idx, err; + unsigned long x, y; + gcm_state gcm; + unsigned char out[2][64], T[2][16]; + + /* find aes */ + idx = find_cipher("aes"); + if (idx == -1) { + idx = find_cipher("rijndael"); + if (idx == -1) { + return CRYPT_NOP; + } + } + + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { + y = sizeof(T[0]); + if ((err = gcm_memory(idx, tests[x].K, tests[x].keylen, + tests[x].IV, tests[x].IVlen, + tests[x].A, tests[x].alen, + (unsigned char*)tests[x].P, tests[x].ptlen, + out[0], T[0], &y, GCM_ENCRYPT)) != CRYPT_OK) { + return err; + } + + if (memcmp(out[0], tests[x].C, tests[x].ptlen)) { +#if 0 + printf("\nCiphertext wrong %lu\n", x); + for (y = 0; y < tests[x].ptlen; y++) { + printf("%02x", out[0][y] & 255); + } + printf("\n"); +#endif + return CRYPT_FAIL_TESTVECTOR; + } + + if (memcmp(T[0], tests[x].T, 16)) { +#if 0 + printf("\nTag on plaintext wrong %lu\n", x); + for (y = 0; y < 16; y++) { + printf("%02x", T[0][y] & 255); + } + printf("\n"); +#endif + return CRYPT_FAIL_TESTVECTOR; + } + + y = sizeof(T[1]); + if ((err = gcm_memory(idx, tests[x].K, tests[x].keylen, + tests[x].IV, tests[x].IVlen, + tests[x].A, tests[x].alen, + out[1], tests[x].ptlen, + out[0], T[1], &y, GCM_DECRYPT)) != CRYPT_OK) { + return err; + } + + if (memcmp(out[1], tests[x].P, tests[x].ptlen)) { +#if 0 + printf("\nplaintext wrong %lu\n", x); + for (y = 0; y < tests[x].ptlen; y++) { + printf("%02x", out[0][y] & 255); + } + printf("\n"); +#endif + return CRYPT_FAIL_TESTVECTOR; + } + + if (memcmp(T[1], tests[x].T, 16)) { +#if 0 + printf("\nTag on ciphertext wrong %lu\n", x); + for (y = 0; y < 16; y++) { + printf("%02x", T[1][y] & 255); + } + printf("\n"); +#endif + return CRYPT_FAIL_TESTVECTOR; + } + + } + return CRYPT_OK; +} + +#endif + diff --git a/src/encauth/ocb/ocb_decrypt.c b/src/encauth/ocb/ocb_decrypt.c index 8fa2c35..d3bf480 100644 --- a/src/encauth/ocb/ocb_decrypt.c +++ b/src/encauth/ocb/ocb_decrypt.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ /** diff --git a/src/encauth/ocb/ocb_decrypt_verify_memory.c b/src/encauth/ocb/ocb_decrypt_verify_memory.c index 2377bab..378a8af 100644 --- a/src/encauth/ocb/ocb_decrypt_verify_memory.c +++ b/src/encauth/ocb/ocb_decrypt_verify_memory.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ /** diff --git a/src/encauth/ocb/ocb_done_decrypt.c b/src/encauth/ocb/ocb_done_decrypt.c index 51e88a2..9f8b1b9 100644 --- a/src/encauth/ocb/ocb_done_decrypt.c +++ b/src/encauth/ocb/ocb_done_decrypt.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ /** diff --git a/src/encauth/ocb/ocb_done_encrypt.c b/src/encauth/ocb/ocb_done_encrypt.c index 3697f80..1a07569 100644 --- a/src/encauth/ocb/ocb_done_encrypt.c +++ b/src/encauth/ocb/ocb_done_encrypt.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ /** diff --git a/src/encauth/ocb/ocb_encrypt.c b/src/encauth/ocb/ocb_encrypt.c index 81fc776..ba39c60 100644 --- a/src/encauth/ocb/ocb_encrypt.c +++ b/src/encauth/ocb/ocb_encrypt.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ /** diff --git a/src/encauth/ocb/ocb_encrypt_authenticate_memory.c b/src/encauth/ocb/ocb_encrypt_authenticate_memory.c index 52741d4..bcc9cfb 100644 --- a/src/encauth/ocb/ocb_encrypt_authenticate_memory.c +++ b/src/encauth/ocb/ocb_encrypt_authenticate_memory.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ /** diff --git a/src/encauth/ocb/ocb_init.c b/src/encauth/ocb/ocb_init.c index 2f7773c..57e04af 100644 --- a/src/encauth/ocb/ocb_init.c +++ b/src/encauth/ocb/ocb_init.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ /** diff --git a/src/encauth/ocb/ocb_ntz.c b/src/encauth/ocb/ocb_ntz.c index 78134f7..4ffe7e8 100644 --- a/src/encauth/ocb/ocb_ntz.c +++ b/src/encauth/ocb/ocb_ntz.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ /** diff --git a/src/encauth/ocb/ocb_shift_xor.c b/src/encauth/ocb/ocb_shift_xor.c index cec1457..b63b022 100644 --- a/src/encauth/ocb/ocb_shift_xor.c +++ b/src/encauth/ocb/ocb_shift_xor.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ /** diff --git a/src/encauth/ocb/ocb_test.c b/src/encauth/ocb/ocb_test.c index 2df19d0..d6cb14b 100644 --- a/src/encauth/ocb/ocb_test.c +++ b/src/encauth/ocb/ocb_test.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ /** diff --git a/src/encauth/ocb/s_ocb_done.c b/src/encauth/ocb/s_ocb_done.c index ea4cbeb..6f6e63d 100644 --- a/src/encauth/ocb/s_ocb_done.c +++ b/src/encauth/ocb/s_ocb_done.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ /** @@ -114,6 +114,7 @@ int s_ocb_done(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen, /* encrypt checksum, er... tag!! */ cipher_descriptor[ocb->cipher].ecb_encrypt(ocb->checksum, X, &ocb->key); + cipher_descriptor[ocb->cipher].done(&ocb->key); /* now store it */ for (x = 0; x < ocb->block_len && x < (int)*taglen; x++) { diff --git a/src/hashes/chc/chc.c b/src/hashes/chc/chc.c index d71d18f..67dd090 100644 --- a/src/hashes/chc/chc.c +++ b/src/hashes/chc/chc.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/hashes/helper/hash_file.c b/src/hashes/helper/hash_file.c index 671b030..78c290a 100644 --- a/src/hashes/helper/hash_file.c +++ b/src/hashes/helper/hash_file.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/hashes/helper/hash_filehandle.c b/src/hashes/helper/hash_filehandle.c index a721c76..c02c5a7 100644 --- a/src/hashes/helper/hash_filehandle.c +++ b/src/hashes/helper/hash_filehandle.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/hashes/helper/hash_memory.c b/src/hashes/helper/hash_memory.c index 6314fe0..9786948 100644 --- a/src/hashes/helper/hash_memory.c +++ b/src/hashes/helper/hash_memory.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/hashes/helper/hash_memory_multi.c b/src/hashes/helper/hash_memory_multi.c index 411a560..ce22283 100644 --- a/src/hashes/helper/hash_memory_multi.c +++ b/src/hashes/helper/hash_memory_multi.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" #include diff --git a/src/hashes/md2.c b/src/hashes/md2.c index 765f69d..5381771 100644 --- a/src/hashes/md2.c +++ b/src/hashes/md2.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/hashes/md4.c b/src/hashes/md4.c index 138cab1..477f5b0 100644 --- a/src/hashes/md4.c +++ b/src/hashes/md4.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/hashes/md5.c b/src/hashes/md5.c index e74f157..e2e5c74 100644 --- a/src/hashes/md5.c +++ b/src/hashes/md5.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/hashes/rmd128.c b/src/hashes/rmd128.c index 8a438fe..1c304a1 100644 --- a/src/hashes/rmd128.c +++ b/src/hashes/rmd128.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/hashes/rmd160.c b/src/hashes/rmd160.c index 0103842..a617152 100644 --- a/src/hashes/rmd160.c +++ b/src/hashes/rmd160.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/hashes/sha1.c b/src/hashes/sha1.c index 27bdb99..267729b 100644 --- a/src/hashes/sha1.c +++ b/src/hashes/sha1.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/hashes/sha2/sha224.c b/src/hashes/sha2/sha224.c index 625da34..8c0dcde 100644 --- a/src/hashes/sha2/sha224.c +++ b/src/hashes/sha2/sha224.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ /** @param sha224.c diff --git a/src/hashes/sha2/sha256.c b/src/hashes/sha2/sha256.c index 318ac57..85eba2a 100644 --- a/src/hashes/sha2/sha256.c +++ b/src/hashes/sha2/sha256.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/hashes/sha2/sha384.c b/src/hashes/sha2/sha384.c index debc768..912145c 100644 --- a/src/hashes/sha2/sha384.c +++ b/src/hashes/sha2/sha384.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ /** @param sha384.c diff --git a/src/hashes/sha2/sha512.c b/src/hashes/sha2/sha512.c index 1cc14db..3238f2b 100644 --- a/src/hashes/sha2/sha512.c +++ b/src/hashes/sha2/sha512.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/hashes/tiger.c b/src/hashes/tiger.c index 12ef7ab..a1cd888 100644 --- a/src/hashes/tiger.c +++ b/src/hashes/tiger.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/hashes/whirl/whirl.c b/src/hashes/whirl/whirl.c index 4902fd6..ff0b436 100644 --- a/src/hashes/whirl/whirl.c +++ b/src/hashes/whirl/whirl.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ /** diff --git a/src/headers/ltc_tommath.h b/src/headers/ltc_tommath.h index dc1c75a..05212e5 100644 --- a/src/headers/ltc_tommath.h +++ b/src/headers/ltc_tommath.h @@ -44,7 +44,7 @@ extern "C" { /* detect 64-bit mode if possible */ #if defined(__x86_64__) - #if !(defined(MP_64BIT) || defined(MP_31BIT) || defined(MP_16BIT) || defined(MP_8BIT)) + #if !(defined(MP_64BIT) && defined(MP_16BIT) && defined(MP_8BIT)) #define MP_64BIT #endif #endif @@ -112,7 +112,7 @@ extern "C" { #else /* prototypes for our heap functions */ extern void *XMALLOC(size_t n); - extern void *REALLOC(void *p, size_t n); + extern void *XREALLOC(void *p, size_t n); extern void *XCALLOC(size_t n, size_t s); extern void XFREE(void *p); #endif @@ -147,7 +147,6 @@ extern "C" { /* Primality generation flags */ #define LTM_PRIME_BBS 0x0001 /* BBS style prime */ #define LTM_PRIME_SAFE 0x0002 /* Safe prime (p-1)/2 == prime */ -#define LTM_PRIME_2MSB_OFF 0x0004 /* force 2nd MSB to 0 */ #define LTM_PRIME_2MSB_ON 0x0008 /* force 2nd MSB to 1 */ typedef int mp_err; @@ -429,6 +428,15 @@ int mp_reduce_2k_setup(mp_int *a, mp_digit *d); /* reduces a modulo b where b is of the form 2**p - k [0 <= a] */ int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d); +/* returns true if a can be reduced with mp_reduce_2k_l */ +int mp_reduce_is_2k_l(mp_int *a); + +/* determines k value for 2k reduction */ +int mp_reduce_2k_setup_l(mp_int *a, mp_int *d); + +/* reduces a modulo b where b is of the form 2**p - k [0 <= a] */ +int mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d); + /* d = a**b (mod c) */ int mp_exptmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d); @@ -509,14 +517,16 @@ int mp_prime_random_ex(mp_int *a, int t, int size, int flags, ltm_prime_callback int mp_count_bits(mp_int *a); int mp_unsigned_bin_size(mp_int *a); -int mp_read_unsigned_bin(mp_int *a, unsigned char *b, int c); +int mp_read_unsigned_bin(mp_int *a, const unsigned char *b, int c); int mp_to_unsigned_bin(mp_int *a, unsigned char *b); +int mp_to_unsigned_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen); int mp_signed_bin_size(mp_int *a); -int mp_read_signed_bin(mp_int *a, unsigned char *b, int c); -int mp_to_signed_bin(mp_int *a, unsigned char *b); +int mp_read_signed_bin(mp_int *a, const unsigned char *b, int c); +int mp_to_signed_bin(mp_int *a, unsigned char *b); +int mp_to_signed_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen); -int mp_read_radix(mp_int *a, char *str, int radix); +int mp_read_radix(mp_int *a, const char *str, int radix); int mp_toradix(mp_int *a, char *str, int radix); int mp_toradix_n(mp_int * a, char *str, int radix, int maxlen); int mp_radix_size(mp_int *a, int radix, int *size); @@ -554,7 +564,7 @@ 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); +int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int mode); void bn_reverse(unsigned char *s, int len); extern const char *mp_s_rmap; diff --git a/src/headers/tomcrypt.h b/src/headers/tomcrypt.h index bd80896..b1745c0 100644 --- a/src/headers/tomcrypt.h +++ b/src/headers/tomcrypt.h @@ -16,8 +16,8 @@ extern "C" { #endif /* version */ -#define CRYPT 0x0100 -#define SCRYPT "1.00" +#define CRYPT 0x0101 +#define SCRYPT "1.01" /* max size of either a cipher/hash block or symmetric key [largest of the two] */ #define MAXBLOCKSIZE 128 @@ -66,6 +66,7 @@ enum { #include #include #include +#include #include #include #include diff --git a/src/headers/tomcrypt_cfg.h b/src/headers/tomcrypt_cfg.h index 8e8f17e..a0022d1 100644 --- a/src/headers/tomcrypt_cfg.h +++ b/src/headers/tomcrypt_cfg.h @@ -9,7 +9,7 @@ /* you can change how memory allocation works ... */ void *XMALLOC(size_t n); -void *REALLOC(void *p, size_t n); +void *XREALLOC(void *p, size_t n); void *XCALLOC(size_t n, size_t s); void XFREE(void *p); @@ -34,6 +34,8 @@ int XMEMCMP(const void *s1, const void *s2, size_t n); #if defined(INTEL_CC) || (defined(_MSC_VER) && defined(WIN32)) || (defined(__GNUC__) && (defined(__DJGPP__) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__i386__))) #define ENDIAN_LITTLE #define ENDIAN_32BITWORD + #define LTC_FAST + #define LTC_FAST_TYPE unsigned long #endif /* detects MIPS R5900 processors (PS2) */ @@ -46,6 +48,26 @@ int XMEMCMP(const void *s1, const void *s2, size_t n); #if defined(__x86_64__) #define ENDIAN_LITTLE #define ENDIAN_64BITWORD + #define LTC_FAST + #define LTC_FAST_TYPE unsigned long +#endif + +#ifdef LTC_NO_FAST + #ifdef LTC_FAST + #undef LTC_FAST + #endif +#endif + +/* No asm is a quick way to disable anything "not portable" */ +#ifdef LTC_NO_ASM + #undef ENDIAN_LITTLE + #undef ENDIAN_BIG + #undef ENDIAN_32BITWORD + #undef ENDIAN_64BITWORD + #undef LTC_FAST + #undef LTC_FAST_TYPE + #define LTC_NO_ROLC + #define LTC_NO_BSWAP #endif /* #define ENDIAN_LITTLE */ diff --git a/src/headers/tomcrypt_cipher.h b/src/headers/tomcrypt_cipher.h index 6d9b555..af184c2 100644 --- a/src/headers/tomcrypt_cipher.h +++ b/src/headers/tomcrypt_cipher.h @@ -164,6 +164,7 @@ typedef union Symmetric_key { #ifdef ANUBIS struct anubis_key anubis; #endif + void *data; } symmetric_key; /* A block cipher ECB structure */ @@ -274,11 +275,109 @@ extern struct ltc_cipher_descriptor { @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled */ int (*test)(void); + + /** Terminate the context + @param skey The scheduled key + */ + void (*done)(symmetric_key *skey); + /** Determine a key size @param keysize [in/out] The size of the key desired and the suggested size @return CRYPT_OK if successful */ int (*keysize)(int *keysize); + +/** Accelerators **/ + /** Accelerated ECB encryption + @param pt Plaintext + @param ct Ciphertext + @param blocks The number of complete blocks to process + @param skey The scheduled key context + */ + void (*accel_ecb_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, symmetric_key *skey); + + /** Accelerated ECB decryption + @param pt Plaintext + @param ct Ciphertext + @param blocks The number of complete blocks to process + @param skey The scheduled key context + */ + void (*accel_ecb_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, symmetric_key *skey); + + /** Accelerated CBC encryption + @param pt Plaintext + @param ct Ciphertext + @param blocks The number of complete blocks to process + @param IV The initial value (input/output) + @param skey The scheduled key context + */ + void (*accel_cbc_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, symmetric_key *skey); + + /** Accelerated CBC decryption + @param pt Plaintext + @param ct Ciphertext + @param blocks The number of complete blocks to process + @param IV The initial value (input/output) + @param skey The scheduled key context + */ + void (*accel_cbc_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, unsigned char *IV, symmetric_key *skey); + + /** Accelerated CTR encryption + @param pt Plaintext + @param ct Ciphertext + @param blocks The number of complete blocks to process + @param IV The initial value (input/output) + @param mode little or big endian counter (mode=0 or mode=1) + @param skey The scheduled key context + */ + void (*accel_ctr_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, int mode, symmetric_key *skey); + + /** Accelerated CCM packet (one-shot) + @param key The secret key to use + @param keylen The length of the secret key (octets) + @param nonce The session nonce [use once] + @param noncelen The length of the nonce + @param header The header for the session + @param headerlen The length of the header (octets) + @param pt [out] The plaintext + @param ptlen The length of the plaintext (octets) + @param ct [out] The ciphertext + @param tag [out] The destination tag + @param taglen [in/out] The max size and resulting size of the authentication tag + @param direction Encrypt or Decrypt direction (0 or 1) + @return CRYPT_OK if successful + */ + void (*accel_ccm_memory)( + const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *header, unsigned long headerlen, + unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, unsigned long *taglen, + int direction); + + /** Accelerated GCM packet (one shot) + @param key The secret key + @param keylen The length of the secret key + @param IV The initial vector + @param IVlen The length of the initial vector + @param adata The additional authentication data (header) + @param adatalen The length of the adata + @param pt The plaintext + @param ptlen The length of the plaintext (ciphertext length is the same) + @param ct The ciphertext + @param tag [out] The MAC tag + @param taglen [in/out] The MAC tag length + @param direction Encrypt or Decrypt mode (GCM_ENCRYPT or GCM_DECRYPT) + */ + void (*accel_gcm_memory)( + const unsigned char *key, unsigned long keylen, + const unsigned char *IV, unsigned long IVlen, + const unsigned char *adata, unsigned long adatalen, + unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, unsigned long *taglen, + int direction); } cipher_descriptor[]; #ifdef BLOWFISH @@ -286,6 +385,7 @@ int blowfish_setup(const unsigned char *key, int keylen, int num_rounds, symmetr void blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); void blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); int blowfish_test(void); +void blowfish_done(symmetric_key *skey); int blowfish_keysize(int *keysize); extern const struct ltc_cipher_descriptor blowfish_desc; #endif @@ -295,6 +395,7 @@ int rc5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_ke void rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); void rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); int rc5_test(void); +void rc5_done(symmetric_key *skey); int rc5_keysize(int *keysize); extern const struct ltc_cipher_descriptor rc5_desc; #endif @@ -304,6 +405,7 @@ int rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_ke void rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); void rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); int rc6_test(void); +void rc6_done(symmetric_key *skey); int rc6_keysize(int *keysize); extern const struct ltc_cipher_descriptor rc6_desc; #endif @@ -313,6 +415,7 @@ int rc2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_ke void rc2_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); void rc2_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); int rc2_test(void); +void rc2_done(symmetric_key *skey); int rc2_keysize(int *keysize); extern const struct ltc_cipher_descriptor rc2_desc; #endif @@ -322,6 +425,7 @@ int saferp_setup(const unsigned char *key, int keylen, int num_rounds, symmetric void saferp_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); void saferp_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); int saferp_test(void); +void saferp_done(symmetric_key *skey); int saferp_keysize(int *keysize); extern const struct ltc_cipher_descriptor saferp_desc; #endif @@ -336,6 +440,7 @@ void safer_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key int safer_k64_test(void); int safer_sk64_test(void); int safer_sk128_test(void); +void safer_done(symmetric_key *skey); int safer_64_keysize(int *keysize); int safer_128_keysize(int *keysize); extern const struct ltc_cipher_descriptor safer_k64_desc, safer_k128_desc, safer_sk64_desc, safer_sk128_desc; @@ -348,6 +453,7 @@ extern const struct ltc_cipher_descriptor safer_k64_desc, safer_k128_desc, safer #define aes_ecb_encrypt rijndael_ecb_encrypt #define aes_ecb_decrypt rijndael_ecb_decrypt #define aes_test rijndael_test +#define aes_done rijndael_done #define aes_keysize rijndael_keysize #define aes_enc_setup rijndael_enc_setup @@ -358,9 +464,11 @@ int rijndael_setup(const unsigned char *key, int keylen, int num_rounds, symmetr void rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); void rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); int rijndael_test(void); +void rijndael_done(symmetric_key *skey); int rijndael_keysize(int *keysize); int rijndael_enc_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); void rijndael_enc_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +void rijndael_enc_done(symmetric_key *skey); int rijndael_enc_keysize(int *keysize); extern const struct ltc_cipher_descriptor rijndael_desc, aes_desc; extern const struct ltc_cipher_descriptor rijndael_enc_desc, aes_enc_desc; @@ -371,6 +479,7 @@ int xtea_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_k void xtea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); void xtea_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); int xtea_test(void); +void xtea_done(symmetric_key *skey); int xtea_keysize(int *keysize); extern const struct ltc_cipher_descriptor xtea_desc; #endif @@ -380,6 +489,7 @@ int twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetri void twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); void twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); int twofish_test(void); +void twofish_done(symmetric_key *skey); int twofish_keysize(int *keysize); extern const struct ltc_cipher_descriptor twofish_desc; #endif @@ -389,11 +499,13 @@ int des_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_ke void des_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); void des_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); int des_test(void); +void des_done(symmetric_key *skey); int des_keysize(int *keysize); int des3_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); void des3_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); void des3_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); int des3_test(void); +void des3_done(symmetric_key *skey); int des3_keysize(int *keysize); extern const struct ltc_cipher_descriptor des_desc, des3_desc; #endif @@ -403,6 +515,7 @@ int cast5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_ void cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); void cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); int cast5_test(void); +void cast5_done(symmetric_key *skey); int cast5_keysize(int *keysize); extern const struct ltc_cipher_descriptor cast5_desc; #endif @@ -412,6 +525,7 @@ int noekeon_setup(const unsigned char *key, int keylen, int num_rounds, symmetri void noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); void noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); int noekeon_test(void); +void noekeon_done(symmetric_key *skey); int noekeon_keysize(int *keysize); extern const struct ltc_cipher_descriptor noekeon_desc; #endif @@ -421,6 +535,7 @@ int skipjack_setup(const unsigned char *key, int keylen, int num_rounds, symmetr void skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); void skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); int skipjack_test(void); +void skipjack_done(symmetric_key *skey); int skipjack_keysize(int *keysize); extern const struct ltc_cipher_descriptor skipjack_desc; #endif @@ -430,6 +545,7 @@ int khazad_setup(const unsigned char *key, int keylen, int num_rounds, symmetric void khazad_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); void khazad_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); int khazad_test(void); +void khazad_done(symmetric_key *skey); int khazad_keysize(int *keysize); extern const struct ltc_cipher_descriptor khazad_desc; #endif @@ -439,6 +555,7 @@ int anubis_setup(const unsigned char *key, int keylen, int num_rounds, symmetric void anubis_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); void anubis_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); int anubis_test(void); +void anubis_done(symmetric_key *skey); int anubis_keysize(int *keysize); extern const struct ltc_cipher_descriptor anubis_desc; #endif @@ -446,8 +563,9 @@ extern const struct ltc_cipher_descriptor anubis_desc; #ifdef ECB int ecb_start(int cipher, const unsigned char *key, int keylen, int num_rounds, symmetric_ECB *ecb); -int ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_ECB *ecb); -int ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_ECB *ecb); +int ecb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_ECB *ecb); +int ecb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_ECB *ecb); +int ecb_done(symmetric_ECB *ecb); #endif #ifdef CFB @@ -457,6 +575,7 @@ int cfb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s int cfb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CFB *cfb); int cfb_getiv(unsigned char *IV, unsigned long *len, symmetric_CFB *cfb); int cfb_setiv(const unsigned char *IV, unsigned long len, symmetric_CFB *cfb); +int cfb_done(symmetric_CFB *cfb); #endif #ifdef OFB @@ -466,15 +585,17 @@ int ofb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s int ofb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_OFB *ofb); int ofb_getiv(unsigned char *IV, unsigned long *len, symmetric_OFB *ofb); int ofb_setiv(const unsigned char *IV, unsigned long len, symmetric_OFB *ofb); +int ofb_done(symmetric_OFB *ofb); #endif #ifdef CBC int cbc_start(int cipher, const unsigned char *IV, const unsigned char *key, int keylen, int num_rounds, symmetric_CBC *cbc); -int cbc_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_CBC *cbc); -int cbc_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_CBC *cbc); +int cbc_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CBC *cbc); +int cbc_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CBC *cbc); int cbc_getiv(unsigned char *IV, unsigned long *len, symmetric_CBC *cbc); int cbc_setiv(const unsigned char *IV, unsigned long len, symmetric_CBC *cbc); +int cbc_done(symmetric_CBC *cbc); #endif #ifdef CTR @@ -484,6 +605,7 @@ int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s int ctr_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CTR *ctr); int ctr_getiv(unsigned char *IV, unsigned long *len, symmetric_CTR *ctr); int ctr_setiv(const unsigned char *IV, unsigned long len, symmetric_CTR *ctr); +int ctr_done(symmetric_CTR *ctr); #endif int find_cipher(const char *name); diff --git a/src/headers/tomcrypt_custom.h b/src/headers/tomcrypt_custom.h index 20415b6..d786f0b 100644 --- a/src/headers/tomcrypt_custom.h +++ b/src/headers/tomcrypt_custom.h @@ -17,19 +17,25 @@ #define XCLOCKS_PER_SEC CLOCKS_PER_SEC /* Use small code where possible */ -// #define LTC_SMALL_CODE +/* #define LTC_SMALL_CODE */ /* Enable self-test test vector checking */ #define LTC_TEST /* clean the stack of functions which put private information on stack */ -// #define LTC_CLEAN_STACK +/* #define LTC_CLEAN_STACK */ /* disable all file related functions */ -// #define LTC_NO_FILE +/* #define LTC_NO_FILE */ /* disable all forms of ASM */ -// #define LTC_NO_ASM +/* #define LTC_NO_ASM */ + +/* disable FAST mode */ +/* #define LTC_NO_FAST */ + +/* disable BSWAP on x86 */ +/* #define LTC_NO_BSWAP */ /* ---> Symmetric Block Ciphers <--- */ #define BLOWFISH @@ -43,17 +49,14 @@ * (saves 4KB of ram), _ALL_TABLES enables all tables during setup */ #define TWOFISH #define TWOFISH_TABLES -// #define TWOFISH_ALL_TABLES -// #define TWOFISH_SMALL +/* #define TWOFISH_ALL_TABLES */ +/* #define TWOFISH_SMALL */ /* DES includes EDE triple-DES */ #define DES #define CAST5 #define NOEKEON #define SKIPJACK -/* SAFER code isn't public domain. It appears to be free to use - * but has been disabled by default to avoid any such problems - */ -//#define SAFER +#define SAFER #define KHAZAD #define ANUBIS #define ANUBIS_TWEAK @@ -85,6 +88,11 @@ #define HMAC #define OMAC #define PMAC +#define PELICAN + +#if defined(PELICAN) && !defined(RIJNDAEL) + #error Pelican-MAC requires RIJNDAEL +#endif /* ---> Encrypt + Authenticate Modes <--- */ #define EAX_MODE @@ -93,6 +101,11 @@ #endif #define OCB_MODE +#define CCM_MODE + +#define GCM_MODE +/* Use 64KiB tables */ +#define GCM_TABLES /* Various tidbits of modern neatoness */ #define BASE64 @@ -100,8 +113,8 @@ /* --> Pseudo Random Number Generators <--- */ /* Yarrow */ #define YARROW -// which descriptor of AES to use? -// 0 = rijndael_enc 1 = aes_enc, 2 = rijndael [full], 3 = aes [full] +/* which descriptor of AES to use? */ +/* 0 = rijndael_enc 1 = aes_enc, 2 = rijndael [full], 3 = aes [full] */ #define YARROW_AES 0 #if defined(YARROW) && !defined(CTR) diff --git a/src/headers/tomcrypt_hash.h b/src/headers/tomcrypt_hash.h index 388d234..d295a59 100644 --- a/src/headers/tomcrypt_hash.h +++ b/src/headers/tomcrypt_hash.h @@ -120,6 +120,7 @@ typedef union Hash_state { #ifdef RIPEMD160 struct rmd160_state rmd160; #endif + void *data; } hash_state; extern struct ltc_hash_descriptor { @@ -321,198 +322,3 @@ int func_name (hash_state * md, const unsigned char *in, unsigned long inlen) } \ return CRYPT_OK; \ } - -#ifdef HMAC -typedef struct Hmac_state { - hash_state md; - int hash; - hash_state hashstate; - unsigned char *key; -} hmac_state; - -int hmac_init(hmac_state *hmac, int hash, const unsigned char *key, unsigned long keylen); -int hmac_process(hmac_state *hmac, const unsigned char *in, unsigned long inlen); -int hmac_done(hmac_state *hmac, unsigned char *out, unsigned long *outlen); -int hmac_test(void); -int hmac_memory(int hash, - const unsigned char *key, unsigned long keylen, - const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen); -int hmac_memory_multi(int hash, - const unsigned char *key, unsigned long keylen, - unsigned char *out, unsigned long *outlen, - const unsigned char *in, unsigned long inlen, ...); -int hmac_file(int hash, const char *fname, const unsigned char *key, - unsigned long keylen, - unsigned char *dst, unsigned long *dstlen); -#endif - -#ifdef OMAC - -typedef struct { - int cipher_idx, - buflen, - blklen; - unsigned char block[MAXBLOCKSIZE], - prev[MAXBLOCKSIZE], - Lu[2][MAXBLOCKSIZE]; - symmetric_key key; -} omac_state; - -int omac_init(omac_state *omac, int cipher, const unsigned char *key, unsigned long keylen); -int omac_process(omac_state *omac, const unsigned char *in, unsigned long inlen); -int omac_done(omac_state *omac, unsigned char *out, unsigned long *outlen); -int omac_memory(int cipher, - const unsigned char *key, unsigned long keylen, - const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen); -int omac_memory_multi(int cipher, - const unsigned char *key, unsigned long keylen, - unsigned char *out, unsigned long *outlen, - const unsigned char *in, unsigned long inlen, ...); -int omac_file(int cipher, - const unsigned char *key, unsigned long keylen, - const char *filename, - unsigned char *out, unsigned long *outlen); -int omac_test(void); -#endif /* OMAC */ - -#ifdef PMAC - -typedef struct { - unsigned char Ls[32][MAXBLOCKSIZE], /* L shifted by i bits to the left */ - Li[MAXBLOCKSIZE], /* value of Li [current value, we calc from previous recall] */ - Lr[MAXBLOCKSIZE], /* L * x^-1 */ - block[MAXBLOCKSIZE], /* currently accumulated block */ - checksum[MAXBLOCKSIZE]; /* current checksum */ - - symmetric_key key; /* scheduled key for cipher */ - unsigned long block_index; /* index # for current block */ - int cipher_idx, /* cipher idx */ - block_len, /* length of block */ - buflen; /* number of bytes in the buffer */ -} pmac_state; - -int pmac_init(pmac_state *pmac, int cipher, const unsigned char *key, unsigned long keylen); -int pmac_process(pmac_state *pmac, const unsigned char *in, unsigned long inlen); -int pmac_done(pmac_state *pmac, unsigned char *out, unsigned long *outlen); - -int pmac_memory(int cipher, - const unsigned char *key, unsigned long keylen, - const unsigned char *msg, unsigned long msglen, - unsigned char *out, unsigned long *outlen); - -int pmac_memory_multi(int cipher, - const unsigned char *key, unsigned long keylen, - unsigned char *out, unsigned long *outlen, - const unsigned char *in, unsigned long inlen, ...); - -int pmac_file(int cipher, - const unsigned char *key, unsigned long keylen, - const char *filename, - unsigned char *out, unsigned long *outlen); - -int pmac_test(void); - -/* internal functions */ -int pmac_ntz(unsigned long x); -void pmac_shift_xor(pmac_state *pmac); - -#endif /* PMAC */ - -#ifdef EAX_MODE - -#if !(defined(OMAC) && defined(CTR)) - #error EAX_MODE requires OMAC and CTR -#endif - -typedef struct { - unsigned char N[MAXBLOCKSIZE]; - symmetric_CTR ctr; - omac_state headeromac, ctomac; -} eax_state; - -int eax_init(eax_state *eax, int cipher, const unsigned char *key, unsigned long keylen, - const unsigned char *nonce, unsigned long noncelen, - const unsigned char *header, unsigned long headerlen); - -int eax_encrypt(eax_state *eax, const unsigned char *pt, unsigned char *ct, unsigned long length); -int eax_decrypt(eax_state *eax, const unsigned char *ct, unsigned char *pt, unsigned long length); -int eax_addheader(eax_state *eax, const unsigned char *header, unsigned long length); -int eax_done(eax_state *eax, unsigned char *tag, unsigned long *taglen); - -int eax_encrypt_authenticate_memory(int cipher, - const unsigned char *key, unsigned long keylen, - const unsigned char *nonce, unsigned long noncelen, - const unsigned char *header, unsigned long headerlen, - const unsigned char *pt, unsigned long ptlen, - unsigned char *ct, - unsigned char *tag, unsigned long *taglen); - -int eax_decrypt_verify_memory(int cipher, - const unsigned char *key, unsigned long keylen, - const unsigned char *nonce, unsigned long noncelen, - const unsigned char *header, unsigned long headerlen, - const unsigned char *ct, unsigned long ctlen, - unsigned char *pt, - unsigned char *tag, unsigned long taglen, - int *stat); - - int eax_test(void); -#endif /* EAX MODE */ - -#ifdef OCB_MODE -typedef struct { - unsigned char L[MAXBLOCKSIZE], /* L value */ - Ls[32][MAXBLOCKSIZE], /* L shifted by i bits to the left */ - Li[MAXBLOCKSIZE], /* value of Li [current value, we calc from previous recall] */ - Lr[MAXBLOCKSIZE], /* L * x^-1 */ - R[MAXBLOCKSIZE], /* R value */ - checksum[MAXBLOCKSIZE]; /* current checksum */ - - symmetric_key key; /* scheduled key for cipher */ - unsigned long block_index; /* index # for current block */ - int cipher, /* cipher idx */ - block_len; /* length of block */ -} ocb_state; - -int ocb_init(ocb_state *ocb, int cipher, - const unsigned char *key, unsigned long keylen, const unsigned char *nonce); - -int ocb_encrypt(ocb_state *ocb, const unsigned char *pt, unsigned char *ct); -int ocb_decrypt(ocb_state *ocb, const unsigned char *ct, unsigned char *pt); - -int ocb_done_encrypt(ocb_state *ocb, - const unsigned char *pt, unsigned long ptlen, - unsigned char *ct, - unsigned char *tag, unsigned long *taglen); - -int ocb_done_decrypt(ocb_state *ocb, - const unsigned char *ct, unsigned long ctlen, - unsigned char *pt, - const unsigned char *tag, unsigned long taglen, int *stat); - -int ocb_encrypt_authenticate_memory(int cipher, - const unsigned char *key, unsigned long keylen, - const unsigned char *nonce, - const unsigned char *pt, unsigned long ptlen, - unsigned char *ct, - unsigned char *tag, unsigned long *taglen); - -int ocb_decrypt_verify_memory(int cipher, - const unsigned char *key, unsigned long keylen, - const unsigned char *nonce, - const unsigned char *ct, unsigned long ctlen, - unsigned char *pt, - const unsigned char *tag, unsigned long taglen, - int *stat); - -int ocb_test(void); - -/* internal functions */ -void ocb_shift_xor(ocb_state *ocb, unsigned char *Z); -int ocb_ntz(unsigned long x); -int s_ocb_done(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen, - unsigned char *ct, unsigned char *tag, unsigned long *taglen, int mode); - -#endif /* OCB_MODE */ diff --git a/src/headers/tomcrypt_mac.h b/src/headers/tomcrypt_mac.h new file mode 100644 index 0000000..6b5e1ce --- /dev/null +++ b/src/headers/tomcrypt_mac.h @@ -0,0 +1,297 @@ +#ifdef HMAC +typedef struct Hmac_state { + hash_state md; + int hash; + hash_state hashstate; + unsigned char *key; +} hmac_state; + +int hmac_init(hmac_state *hmac, int hash, const unsigned char *key, unsigned long keylen); +int hmac_process(hmac_state *hmac, const unsigned char *in, unsigned long inlen); +int hmac_done(hmac_state *hmac, unsigned char *out, unsigned long *outlen); +int hmac_test(void); +int hmac_memory(int hash, + const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int hmac_memory_multi(int hash, + const unsigned char *key, unsigned long keylen, + unsigned char *out, unsigned long *outlen, + const unsigned char *in, unsigned long inlen, ...); +int hmac_file(int hash, const char *fname, const unsigned char *key, + unsigned long keylen, + unsigned char *dst, unsigned long *dstlen); +#endif + +#ifdef OMAC + +typedef struct { + int cipher_idx, + buflen, + blklen; + unsigned char block[MAXBLOCKSIZE], + prev[MAXBLOCKSIZE], + Lu[2][MAXBLOCKSIZE]; + symmetric_key key; +} omac_state; + +int omac_init(omac_state *omac, int cipher, const unsigned char *key, unsigned long keylen); +int omac_process(omac_state *omac, const unsigned char *in, unsigned long inlen); +int omac_done(omac_state *omac, unsigned char *out, unsigned long *outlen); +int omac_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int omac_memory_multi(int cipher, + const unsigned char *key, unsigned long keylen, + unsigned char *out, unsigned long *outlen, + const unsigned char *in, unsigned long inlen, ...); +int omac_file(int cipher, + const unsigned char *key, unsigned long keylen, + const char *filename, + unsigned char *out, unsigned long *outlen); +int omac_test(void); +#endif /* OMAC */ + +#ifdef PMAC + +typedef struct { + unsigned char Ls[32][MAXBLOCKSIZE], /* L shifted by i bits to the left */ + Li[MAXBLOCKSIZE], /* value of Li [current value, we calc from previous recall] */ + Lr[MAXBLOCKSIZE], /* L * x^-1 */ + block[MAXBLOCKSIZE], /* currently accumulated block */ + checksum[MAXBLOCKSIZE]; /* current checksum */ + + symmetric_key key; /* scheduled key for cipher */ + unsigned long block_index; /* index # for current block */ + int cipher_idx, /* cipher idx */ + block_len, /* length of block */ + buflen; /* number of bytes in the buffer */ +} pmac_state; + +int pmac_init(pmac_state *pmac, int cipher, const unsigned char *key, unsigned long keylen); +int pmac_process(pmac_state *pmac, const unsigned char *in, unsigned long inlen); +int pmac_done(pmac_state *pmac, unsigned char *out, unsigned long *outlen); + +int pmac_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *msg, unsigned long msglen, + unsigned char *out, unsigned long *outlen); + +int pmac_memory_multi(int cipher, + const unsigned char *key, unsigned long keylen, + unsigned char *out, unsigned long *outlen, + const unsigned char *in, unsigned long inlen, ...); + +int pmac_file(int cipher, + const unsigned char *key, unsigned long keylen, + const char *filename, + unsigned char *out, unsigned long *outlen); + +int pmac_test(void); + +/* internal functions */ +int pmac_ntz(unsigned long x); +void pmac_shift_xor(pmac_state *pmac); + +#endif /* PMAC */ + +#ifdef EAX_MODE + +#if !(defined(OMAC) && defined(CTR)) + #error EAX_MODE requires OMAC and CTR +#endif + +typedef struct { + unsigned char N[MAXBLOCKSIZE]; + symmetric_CTR ctr; + omac_state headeromac, ctomac; +} eax_state; + +int eax_init(eax_state *eax, int cipher, const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *header, unsigned long headerlen); + +int eax_encrypt(eax_state *eax, const unsigned char *pt, unsigned char *ct, unsigned long length); +int eax_decrypt(eax_state *eax, const unsigned char *ct, unsigned char *pt, unsigned long length); +int eax_addheader(eax_state *eax, const unsigned char *header, unsigned long length); +int eax_done(eax_state *eax, unsigned char *tag, unsigned long *taglen); + +int eax_encrypt_authenticate_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *header, unsigned long headerlen, + const unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, unsigned long *taglen); + +int eax_decrypt_verify_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *header, unsigned long headerlen, + const unsigned char *ct, unsigned long ctlen, + unsigned char *pt, + unsigned char *tag, unsigned long taglen, + int *stat); + + int eax_test(void); +#endif /* EAX MODE */ + +#ifdef OCB_MODE +typedef struct { + unsigned char L[MAXBLOCKSIZE], /* L value */ + Ls[32][MAXBLOCKSIZE], /* L shifted by i bits to the left */ + Li[MAXBLOCKSIZE], /* value of Li [current value, we calc from previous recall] */ + Lr[MAXBLOCKSIZE], /* L * x^-1 */ + R[MAXBLOCKSIZE], /* R value */ + checksum[MAXBLOCKSIZE]; /* current checksum */ + + symmetric_key key; /* scheduled key for cipher */ + unsigned long block_index; /* index # for current block */ + int cipher, /* cipher idx */ + block_len; /* length of block */ +} ocb_state; + +int ocb_init(ocb_state *ocb, int cipher, + const unsigned char *key, unsigned long keylen, const unsigned char *nonce); + +int ocb_encrypt(ocb_state *ocb, const unsigned char *pt, unsigned char *ct); +int ocb_decrypt(ocb_state *ocb, const unsigned char *ct, unsigned char *pt); + +int ocb_done_encrypt(ocb_state *ocb, + const unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, unsigned long *taglen); + +int ocb_done_decrypt(ocb_state *ocb, + const unsigned char *ct, unsigned long ctlen, + unsigned char *pt, + const unsigned char *tag, unsigned long taglen, int *stat); + +int ocb_encrypt_authenticate_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, + const unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, unsigned long *taglen); + +int ocb_decrypt_verify_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, + const unsigned char *ct, unsigned long ctlen, + unsigned char *pt, + const unsigned char *tag, unsigned long taglen, + int *stat); + +int ocb_test(void); + +/* internal functions */ +void ocb_shift_xor(ocb_state *ocb, unsigned char *Z); +int ocb_ntz(unsigned long x); +int s_ocb_done(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen, + unsigned char *ct, unsigned char *tag, unsigned long *taglen, int mode); + +#endif /* OCB_MODE */ + +#ifdef CCM_MODE + +#define CCM_ENCRYPT 0 +#define CCM_DECRYPT 1 + +int ccm_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *header, unsigned long headerlen, + unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, unsigned long *taglen, + int direction); + +int ccm_test(void); + +#endif /* CCM_MODE */ + +#ifdef GCM_MODE + +#define GCM_ENCRYPT 0 +#define GCM_DECRYPT 1 + +#define GCM_MODE_IV 0 +#define GCM_MODE_AAD 1 +#define GCM_MODE_TEXT 2 + +typedef struct { + symmetric_key K; + unsigned char H[16], /* multiplier */ + X[16], /* accumulator */ + Y[16], /* counter */ + Y_0[16], /* initial counter */ + buf[16]; /* buffer for stuff */ + + int cipher, /* which cipher */ + ivmode, /* Which mode is the IV in? */ + mode, /* mode the GCM code is in */ + buflen; /* length of data in buf */ + + ulong64 totlen, /* 64-bit counter used for IV and AAD */ + pttotlen; /* 64-bit counter for the PT */ + +#ifdef GCM_TABLES + unsigned char PC[16][256][16]; /* 16 tables of 8x128 */ +#endif + +} gcm_state; + +void gcm_gf_mult(const unsigned char *a, const unsigned char *b, unsigned char *c); +void gcm_mult_h(gcm_state *gcm, unsigned char *I); + +int gcm_init(gcm_state *gcm, int cipher, + const unsigned char *key, int keylen); + +int gcm_reset(gcm_state *gcm); + +int gcm_add_iv(gcm_state *gcm, + const unsigned char *IV, unsigned long IVlen); + +int gcm_add_aad(gcm_state *gcm, + const unsigned char *adata, unsigned long adatalen); + +int gcm_process(gcm_state *gcm, + unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + int direction); + +int gcm_done(gcm_state *gcm, + unsigned char *tag, unsigned long *taglen); + +int gcm_memory( int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *IV, unsigned long IVlen, + const unsigned char *adata, unsigned long adatalen, + unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, unsigned long *taglen, + int direction); +int gcm_test(void); + +#endif /* GCM_MODE */ + +#ifdef PELICAN + +typedef struct pelican_state +{ + symmetric_key K; + unsigned char state[16]; + int buflen; +} pelican_state; + +int pelican_init(pelican_state *pelmac, const unsigned char *key, unsigned long keylen); +int pelican_process(pelican_state *pelmac, const unsigned char *in, unsigned long inlen); +int pelican_done(pelican_state *pelmac, unsigned char *out); +int pelican_test(void); + +int pelican_memory(const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + unsigned char *out); + +#endif diff --git a/src/headers/tomcrypt_macros.h b/src/headers/tomcrypt_macros.h index 971cb9c..f083984 100644 --- a/src/headers/tomcrypt_macros.h +++ b/src/headers/tomcrypt_macros.h @@ -67,6 +67,23 @@ #ifdef ENDIAN_LITTLE +#if !defined(LTC_NO_BSWAP) && (defined(INTEL_CC) || (defined(__GNUC__) && (defined(__DJGPP__) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__i386__) || defined(__x86_64__)))) + +#define STORE32H(x, y) \ +asm __volatile__ ( \ + "bswapl %0 \n\t" \ + "movl %0,(%2)\n\t" \ + "bswapl %0 \n\t" \ + :"=r"(x):"0"(x), "r"(y)); + +#define LOAD32H(x, y) \ +asm __volatile__ ( \ + "movl (%2),%0\n\t" \ + "bswapl %0\n\t" \ + :"=r"(x): "0"(x), "r"(y)); + +#else + #define STORE32H(x, y) \ { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \ (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); } @@ -77,6 +94,27 @@ ((unsigned long)((y)[2] & 255)<<8) | \ ((unsigned long)((y)[3] & 255)); } +#endif + + +/* x86_64 processor */ +#if !defined(LTC_NO_BSWAP) && (defined(__GNUC__) && defined(__x86_64__)) + +#define STORE64H(x, y) \ +asm __volatile__ ( \ + "bswapq %0 \n\t" \ + "movq %0,(%2)\n\t" \ + "bswapq %0 \n\t" \ + :"=r"(x):"0"(x), "r"(y):"0"); + +#define LOAD64H(x, y) \ +asm __volatile__ ( \ + "movq (%2),%0\n\t" \ + "bswapq %0\n\t" \ + :"=r"(x): "0"(x), "r"(y)); + +#else + #define STORE64H(x, y) \ { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \ (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \ @@ -89,6 +127,8 @@ (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \ (((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); } +#endif + #ifdef ENDIAN_32BITWORD #define STORE32L(x, y) \ @@ -295,8 +335,8 @@ static inline unsigned long ROR64c(unsigned long word, const int i) #else /* LTC_NO_ROLC */ -#define ROL64c ROL -#define ROR64c ROR +#define ROL64c ROL64 +#define ROR64c ROR64 #endif diff --git a/src/headers/tomcrypt_pk.h b/src/headers/tomcrypt_pk.h index b1254db..065ca99 100644 --- a/src/headers/tomcrypt_pk.h +++ b/src/headers/tomcrypt_pk.h @@ -193,7 +193,7 @@ int dh_verify_hash(const unsigned char *sig, unsigned long siglen, /* ---- ECC Routines ---- */ #ifdef MECC typedef struct { - mp_int x, y; + mp_int x, y, z; } ecc_point; typedef struct { diff --git a/src/headers/tommath_class.h b/src/headers/tommath_class.h index 3dc21a1..6d05b7b 100644 --- a/src/headers/tommath_class.h +++ b/src/headers/tommath_class.h @@ -90,8 +90,11 @@ #define BN_MP_READ_UNSIGNED_BIN_C #define BN_MP_REDUCE_C #define BN_MP_REDUCE_2K_C +#define BN_MP_REDUCE_2K_L_C #define BN_MP_REDUCE_2K_SETUP_C +#define BN_MP_REDUCE_2K_SETUP_L_C #define BN_MP_REDUCE_IS_2K_C +#define BN_MP_REDUCE_IS_2K_L_C #define BN_MP_REDUCE_SETUP_C #define BN_MP_RSHD_C #define BN_MP_SET_C @@ -105,7 +108,9 @@ #define BN_MP_SUB_D_C #define BN_MP_SUBMOD_C #define BN_MP_TO_SIGNED_BIN_C +#define BN_MP_TO_SIGNED_BIN_N_C #define BN_MP_TO_UNSIGNED_BIN_C +#define BN_MP_TO_UNSIGNED_BIN_N_C #define BN_MP_TOOM_MUL_C #define BN_MP_TOOM_SQR_C #define BN_MP_TORADIX_C @@ -132,7 +137,7 @@ #define BN_MP_ISEVEN_C #define BN_MP_INIT_MULTI_C #define BN_MP_COPY_C - #define BN_MP_ABS_C + #define BN_MP_MOD_C #define BN_MP_SET_C #define BN_MP_DIV_2_C #define BN_MP_ISODD_C @@ -324,11 +329,12 @@ #define BN_MP_CLEAR_C #define BN_MP_ABS_C #define BN_MP_CLEAR_MULTI_C + #define BN_MP_REDUCE_IS_2K_L_C + #define BN_S_MP_EXPTMOD_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) @@ -360,6 +366,7 @@ #define BN_MP_DIV_C #define BN_MP_MUL_C #define BN_MP_SUB_C + #define BN_MP_NEG_C #define BN_MP_EXCH_C #define BN_MP_CLEAR_MULTI_C #endif @@ -434,6 +441,7 @@ #if defined(BN_MP_INVMOD_SLOW_C) #define BN_MP_ISZERO_C #define BN_MP_INIT_MULTI_C + #define BN_MP_MOD_C #define BN_MP_COPY_C #define BN_MP_ISEVEN_C #define BN_MP_SET_C @@ -659,9 +667,9 @@ #endif #if defined(BN_MP_RADIX_SIZE_C) - #define BN_MP_ISZERO_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 @@ -700,8 +708,8 @@ #define BN_MP_INIT_COPY_C #define BN_MP_RSHD_C #define BN_MP_MUL_C - #define BN_FAST_S_MP_MUL_HIGH_DIGS_C #define BN_S_MP_MUL_HIGH_DIGS_C + #define BN_FAST_S_MP_MUL_HIGH_DIGS_C #define BN_MP_MOD_2D_C #define BN_S_MP_MUL_DIGS_C #define BN_MP_SUB_C @@ -725,6 +733,17 @@ #define BN_MP_CLEAR_C #endif +#if defined(BN_MP_REDUCE_2K_L_C) + #define BN_MP_INIT_C + #define BN_MP_COUNT_BITS_C + #define BN_MP_DIV_2D_C + #define BN_MP_MUL_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 @@ -733,11 +752,22 @@ #define BN_S_MP_SUB_C #endif +#if defined(BN_MP_REDUCE_2K_SETUP_L_C) + #define BN_MP_INIT_C + #define BN_MP_2EXPT_C + #define BN_MP_COUNT_BITS_C + #define BN_S_MP_SUB_C + #define BN_MP_CLEAR_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_IS_2K_L_C) +#endif + #if defined(BN_MP_REDUCE_SETUP_C) #define BN_MP_2EXPT_C #define BN_MP_DIV_C @@ -815,6 +845,11 @@ #define BN_MP_TO_UNSIGNED_BIN_C #endif +#if defined(BN_MP_TO_SIGNED_BIN_N_C) + #define BN_MP_SIGNED_BIN_SIZE_C + #define BN_MP_TO_SIGNED_BIN_C +#endif + #if defined(BN_MP_TO_UNSIGNED_BIN_C) #define BN_MP_INIT_COPY_C #define BN_MP_ISZERO_C @@ -822,6 +857,11 @@ #define BN_MP_CLEAR_C #endif +#if defined(BN_MP_TO_UNSIGNED_BIN_N_C) + #define BN_MP_UNSIGNED_BIN_SIZE_C + #define BN_MP_TO_UNSIGNED_BIN_C +#endif + #if defined(BN_MP_TOOM_MUL_C) #define BN_MP_INIT_MULTI_C #define BN_MP_MOD_2D_C @@ -902,10 +942,12 @@ #define BN_MP_INIT_C #define BN_MP_CLEAR_C #define BN_MP_REDUCE_SETUP_C + #define BN_MP_REDUCE_C + #define BN_MP_REDUCE_2K_SETUP_L_C + #define BN_MP_REDUCE_2K_L_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 diff --git a/src/headers/tommath_superclass.h b/src/headers/tommath_superclass.h index 7b6c05a..b50ecb0 100644 --- a/src/headers/tommath_superclass.h +++ b/src/headers/tommath_superclass.h @@ -7,7 +7,9 @@ // #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 */ @@ -32,7 +34,7 @@ #define BN_PRIME_TAB_C /* other modifiers */ - #define BN_MP_DIV_SMALL /* Slower division, not critical */ + #define BN_MP_DIV_SMALL /* Slower division, not critical */ /* 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 diff --git a/src/mac/hmac/hmac_done.c b/src/mac/hmac/hmac_done.c index 9bc9f69..fdf20be 100644 --- a/src/mac/hmac/hmac_done.c +++ b/src/mac/hmac/hmac_done.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/mac/hmac/hmac_file.c b/src/mac/hmac/hmac_file.c index c726e50..edbb6a6 100644 --- a/src/mac/hmac/hmac_file.c +++ b/src/mac/hmac/hmac_file.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/mac/hmac/hmac_init.c b/src/mac/hmac/hmac_init.c index 3f7d8c2..d060a5b 100644 --- a/src/mac/hmac/hmac_init.c +++ b/src/mac/hmac/hmac_init.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/mac/hmac/hmac_memory.c b/src/mac/hmac/hmac_memory.c index 804e06d..036ee36 100644 --- a/src/mac/hmac/hmac_memory.c +++ b/src/mac/hmac/hmac_memory.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/mac/hmac/hmac_memory_multi.c b/src/mac/hmac/hmac_memory_multi.c index f45776a..4a5b9be 100644 --- a/src/mac/hmac/hmac_memory_multi.c +++ b/src/mac/hmac/hmac_memory_multi.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" #include diff --git a/src/mac/hmac/hmac_process.c b/src/mac/hmac/hmac_process.c index 265293f..30e64c3 100644 --- a/src/mac/hmac/hmac_process.c +++ b/src/mac/hmac/hmac_process.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/mac/hmac/hmac_test.c b/src/mac/hmac/hmac_test.c index 6ff749f..0d542d4 100644 --- a/src/mac/hmac/hmac_test.c +++ b/src/mac/hmac/hmac_test.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/mac/omac/omac_done.c b/src/mac/omac/omac_done.c index e2c9b7c..0a91a14 100644 --- a/src/mac/omac/omac_done.c +++ b/src/mac/omac/omac_done.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" @@ -62,6 +62,7 @@ int omac_done(omac_state *omac, unsigned char *out, unsigned long *outlen) /* encrypt it */ cipher_descriptor[omac->cipher_idx].ecb_encrypt(omac->block, omac->block, &omac->key); + cipher_descriptor[omac->cipher_idx].done(&omac->key); /* output it */ for (x = 0; x < (unsigned)omac->blklen && x < *outlen; x++) { diff --git a/src/mac/omac/omac_file.c b/src/mac/omac/omac_file.c index 25e8c50..1e3d2f6 100644 --- a/src/mac/omac/omac_file.c +++ b/src/mac/omac/omac_file.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/mac/omac/omac_init.c b/src/mac/omac/omac_init.c index 98ca640..d39219d 100644 --- a/src/mac/omac/omac_init.c +++ b/src/mac/omac/omac_init.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" @@ -38,6 +38,12 @@ int omac_init(omac_state *omac, int cipher, const unsigned char *key, unsigned l return err; } +#ifdef LTC_FAST + if (16 % sizeof(LTC_FAST_TYPE)) { + return CRYPT_INVALID_ARG; + } +#endif + /* now setup the system */ switch (cipher_descriptor[cipher].block_length) { case 8: mask = 0x1B; diff --git a/src/mac/omac/omac_memory.c b/src/mac/omac/omac_memory.c index f9a025d..51d0ce2 100644 --- a/src/mac/omac/omac_memory.c +++ b/src/mac/omac/omac_memory.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/mac/omac/omac_memory_multi.c b/src/mac/omac/omac_memory_multi.c index 9bd31e8..76e4eb0 100644 --- a/src/mac/omac/omac_memory_multi.c +++ b/src/mac/omac/omac_memory_multi.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" #include diff --git a/src/mac/omac/omac_process.c b/src/mac/omac/omac_process.c index e5f3147..6b603f7 100644 --- a/src/mac/omac/omac_process.c +++ b/src/mac/omac/omac_process.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" @@ -40,6 +40,20 @@ int omac_process(omac_state *omac, const unsigned char *in, unsigned long inlen) return CRYPT_INVALID_ARG; } +#ifdef LTC_FAST + if (omac->buflen == 0 && inlen > 16) { + int y; + for (x = 0; x < (inlen - 16); x += 16) { + for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) { + *((LTC_FAST_TYPE*)(&omac->prev[y])) ^= *((LTC_FAST_TYPE*)(&in[y])); + } + in += 16; + cipher_descriptor[omac->cipher_idx].ecb_encrypt(omac->prev, omac->prev, &omac->key); + } + inlen -= x; + } +#endif + while (inlen != 0) { /* ok if the block is full we xor in prev, encrypt and replace prev */ if (omac->buflen == omac->blklen) { @@ -53,7 +67,7 @@ int omac_process(omac_state *omac, const unsigned char *in, unsigned long inlen) /* add bytes */ n = MIN(inlen, (unsigned long)(omac->blklen - omac->buflen)); XMEMCPY(omac->block + omac->buflen, in, n); - omac->buflen += n; + omac->buflen += n; inlen -= n; in += n; } diff --git a/src/mac/omac/omac_test.c b/src/mac/omac/omac_test.c index f6cabdf..42e42bd 100644 --- a/src/mac/omac/omac_test.c +++ b/src/mac/omac/omac_test.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/mac/pelican/pelican.c b/src/mac/pelican/pelican.c new file mode 100644 index 0000000..d47bd56 --- /dev/null +++ b/src/mac/pelican/pelican.c @@ -0,0 +1,149 @@ +/* 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@gmail.com, http://libtomcrypt.org + */ +#include "tomcrypt.h" + +/** + @file pelican.c + Pelican MAC, initialize state, by Tom St Denis +*/ + +#ifdef PELICAN + +#define ENCRYPT_ONLY +#include "../../ciphers/aes/aes_tab.c" + + +/** + Initialize a Pelican state + @param pelmac The Pelican state to initialize + @param key The secret key + @param keylen The length of the secret key (octets) + @return CRYPT_OK if successful +*/ +int pelican_init(pelican_state *pelmac, const unsigned char *key, unsigned long keylen) +{ + int err; + + LTC_ARGCHK(pelmac != NULL); + LTC_ARGCHK(key != NULL); + +#ifdef LTC_FAST + if (16 % sizeof(LTC_FAST_TYPE)) { + return CRYPT_INVALID_ARG; + } +#endif + + if ((err = aes_setup(key, keylen, 0, &pelmac->K)) != CRYPT_OK) { + return err; + } + + zeromem(pelmac->state, 16); + aes_ecb_encrypt(pelmac->state, pelmac->state, &pelmac->K); + pelmac->buflen = 0; + + return CRYPT_OK; +} + +static void four_rounds(pelican_state *pelmac) +{ + ulong32 s0, s1, s2, s3, t0, t1, t2, t3; + int r; + + LOAD32H(s0, pelmac->state ); + LOAD32H(s1, pelmac->state + 4); + LOAD32H(s2, pelmac->state + 8); + LOAD32H(s3, pelmac->state + 12); + for (r = 0; r < 4; r++) { + t0 = + Te0(byte(s0, 3)) ^ + Te1(byte(s1, 2)) ^ + Te2(byte(s2, 1)) ^ + Te3(byte(s3, 0)); + t1 = + Te0(byte(s1, 3)) ^ + Te1(byte(s2, 2)) ^ + Te2(byte(s3, 1)) ^ + Te3(byte(s0, 0)); + t2 = + Te0(byte(s2, 3)) ^ + Te1(byte(s3, 2)) ^ + Te2(byte(s0, 1)) ^ + Te3(byte(s1, 0)); + t3 = + Te0(byte(s3, 3)) ^ + Te1(byte(s0, 2)) ^ + Te2(byte(s1, 1)) ^ + Te3(byte(s2, 0)); + s0 = t0; s1 = t1; s2 = t2; s3 = t3; + } + STORE32H(s0, pelmac->state ); + STORE32H(s1, pelmac->state + 4); + STORE32H(s2, pelmac->state + 8); + STORE32H(s3, pelmac->state + 12); +} + +/** + Process a block of text through Pelican + @param pelmac The Pelican MAC state + @param in The input + @param inlen The length input (octets) + @return CRYPT_OK on success + */ +int pelican_process(pelican_state *pelmac, const unsigned char *in, unsigned long inlen) +{ + + LTC_ARGCHK(pelmac != NULL); + LTC_ARGCHK(in != NULL); +#ifdef LTC_FAST + if (pelmac->buflen == 0) { + while (inlen & ~15) { + int x; + for (x = 0; x < 16; x += sizeof(LTC_FAST_TYPE)) { + *((LTC_FAST_TYPE*)((unsigned char *)pelmac->state + x)) ^= *((LTC_FAST_TYPE*)((unsigned char *)in + x)); + } + four_rounds(pelmac); + in += 16; + inlen -= 16; + } + } +#endif + + while (inlen--) { + pelmac->state[pelmac->buflen++] ^= *in++; + if (pelmac->buflen == 16) { + four_rounds(pelmac); + pelmac->buflen = 0; + } + } + return CRYPT_OK; +} + +/** + Terminate Pelican MAC + @param pelmac The Pelican MAC state + @param out [out] The TAG + @return CRYPT_OK on sucess +*/ +int pelican_done(pelican_state *pelmac, unsigned char *out) +{ + LTC_ARGCHK(pelmac != NULL); + LTC_ARGCHK(out != NULL); + if (pelmac->buflen == 16) { + four_rounds(pelmac); + pelmac->buflen = 0; + } + pelmac->state[pelmac->buflen++] ^= 0x80; + aes_ecb_encrypt(pelmac->state, out, &pelmac->K); + aes_done(&pelmac->K); + return CRYPT_OK; +} + +#endif diff --git a/src/mac/pelican/pelican_memory.c b/src/mac/pelican/pelican_memory.c new file mode 100644 index 0000000..9e0fc7b --- /dev/null +++ b/src/mac/pelican/pelican_memory.c @@ -0,0 +1,55 @@ +/* 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@gmail.com, http://libtomcrypt.org + */ +#include "tomcrypt.h" + +/** + @file pelican_memory.c + Pelican MAC, MAC a block of memory, by Tom St Denis +*/ + +#ifdef PELICAN + +/** + Pelican block of memory + @param key The key for the MAC + @param keylen The length of the key (octets) + @param in The input to MAC + @param inlen The length of the input (octets) + @param out [out] The output TAG + @return CRYPT_OK on success +*/ +int pelican_memory(const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + unsigned char *out) +{ + pelican_state *pel; + int err; + + pel = XMALLOC(sizeof(*pel)); + if (pel == NULL) { + return CRYPT_MEM; + } + + if ((err = pelican_init(pel, key, keylen)) != CRYPT_OK) { + XFREE(pel); + return err; + } + if ((err = pelican_process(pel, in ,inlen)) != CRYPT_OK) { + XFREE(pel); + return err; + } + err = pelican_done(pel, out); + XFREE(pel); + return err; +} + + +#endif diff --git a/src/mac/pelican/pelican_test.c b/src/mac/pelican/pelican_test.c new file mode 100644 index 0000000..e694f61 --- /dev/null +++ b/src/mac/pelican/pelican_test.c @@ -0,0 +1,116 @@ +/* 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@gmail.com, http://libtomcrypt.org + */ +#include "tomcrypt.h" + +/** + @file pelican_test.c + Pelican MAC, test, by Tom St Denis +*/ + +#ifdef PELICAN + +int pelican_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + static const struct { + unsigned char K[32], MSG[64], T[16]; + int keylen, ptlen; + } tests[] = { +/* K=16, M=0 */ +{ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }, + { 0 }, + { 0xeb, 0x58, 0x37, 0x15, 0xf8, 0x34, 0xde, 0xe5, + 0xa4, 0xd1, 0x6e, 0xe4, 0xb9, 0xd7, 0x76, 0x0e, }, + 16, 0 +}, + +/* K=16, M=3 */ +{ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }, + { 0x00, 0x01, 0x02 }, + { 0x1c, 0x97, 0x40, 0x60, 0x6c, 0x58, 0x17, 0x2d, + 0x03, 0x94, 0x19, 0x70, 0x81, 0xc4, 0x38, 0x54, }, + 16, 3 +}, + +/* K=16, M=16 */ +{ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }, + { 0x03, 0xcc, 0x46, 0xb8, 0xac, 0xa7, 0x9c, 0x36, + 0x1e, 0x8c, 0x6e, 0xa6, 0x7b, 0x89, 0x32, 0x49, }, + 16, 16 +}, + +/* K=16, M=32 */ +{ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F }, + { 0x89, 0xcc, 0x36, 0x58, 0x1b, 0xdd, 0x4d, 0xb5, + 0x78, 0xbb, 0xac, 0xf0, 0xff, 0x8b, 0x08, 0x15, }, + 16, 32 +}, + +/* K=16, M=35 */ +{ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, + 0x20, 0x21, 0x23 }, + { 0x4a, 0x7d, 0x45, 0x4d, 0xcd, 0xb5, 0xda, 0x8d, + 0x48, 0x78, 0x16, 0x48, 0x5d, 0x45, 0x95, 0x99, }, + 16, 35 +}, +}; + int x, err; + unsigned char out[16]; + pelican_state pel; + + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { + if ((err = pelican_init(&pel, tests[x].K, tests[x].keylen)) != CRYPT_OK) { + return err; + } + if ((err = pelican_process(&pel, tests[x].MSG, tests[x].ptlen)) != CRYPT_OK) { + return err; + } + if ((err = pelican_done(&pel, out)) != CRYPT_OK) { + return err; + } + + if (memcmp(out, tests[x].T, 16)) { +#if 0 + int y; + printf("\nFailed test %d\n", x); + printf("{ "); for (y = 0; y < 16; ) { printf("0x%02x, ", out[y]); if (!(++y & 7)) printf("\n"); } printf(" }\n"); +#endif + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; +#endif +} + + +#endif diff --git a/src/mac/pmac/pmac_done.c b/src/mac/pmac/pmac_done.c index 384a5b8..610e433 100644 --- a/src/mac/pmac/pmac_done.c +++ b/src/mac/pmac/pmac_done.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" @@ -50,6 +50,7 @@ int pmac_done(pmac_state *state, unsigned char *out, unsigned long *outlen) /* encrypt it */ cipher_descriptor[state->cipher_idx].ecb_encrypt(state->checksum, state->checksum, &state->key); + cipher_descriptor[state->cipher_idx].done(&state->key); /* store it */ for (x = 0; x < state->block_len && x <= (int)*outlen; x++) { diff --git a/src/mac/pmac/pmac_file.c b/src/mac/pmac/pmac_file.c index f2ea7f4..5b7dd24 100644 --- a/src/mac/pmac/pmac_file.c +++ b/src/mac/pmac/pmac_file.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/mac/pmac/pmac_init.c b/src/mac/pmac/pmac_init.c index 0f9e838..a02b20c 100644 --- a/src/mac/pmac/pmac_init.c +++ b/src/mac/pmac/pmac_init.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" @@ -65,7 +65,14 @@ int pmac_init(pmac_state *pmac, int cipher, const unsigned char *key, unsigned l } if (polys[poly].len != pmac->block_len) { return CRYPT_INVALID_ARG; - } + } + +#ifdef LTC_FAST + if (pmac->block_len % sizeof(LTC_FAST_TYPE)) { + return CRYPT_INVALID_ARG; + } +#endif + /* schedule the key */ if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &pmac->key)) != CRYPT_OK) { diff --git a/src/mac/pmac/pmac_memory.c b/src/mac/pmac/pmac_memory.c index 6a97003..a04cd78 100644 --- a/src/mac/pmac/pmac_memory.c +++ b/src/mac/pmac/pmac_memory.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/mac/pmac/pmac_memory_multi.c b/src/mac/pmac/pmac_memory_multi.c index c1481fc..289d2e0 100644 --- a/src/mac/pmac/pmac_memory_multi.c +++ b/src/mac/pmac/pmac_memory_multi.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" #include @@ -31,9 +31,9 @@ @return CRYPT_OK if successful */ int pmac_memory_multi(int cipher, - const unsigned char *key, unsigned long keylen, + const unsigned char *key, unsigned long keylen, unsigned char *out, unsigned long *outlen, - const unsigned char *in, unsigned long inlen, ...) + const unsigned char *in, unsigned long inlen, ...) { int err; pmac_state *pmac; diff --git a/src/mac/pmac/pmac_ntz.c b/src/mac/pmac/pmac_ntz.c index 45970b3..97f0a15 100644 --- a/src/mac/pmac/pmac_ntz.c +++ b/src/mac/pmac/pmac_ntz.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/mac/pmac/pmac_process.c b/src/mac/pmac/pmac_process.c index 0f68e90..5cee5ec 100644 --- a/src/mac/pmac/pmac_process.c +++ b/src/mac/pmac/pmac_process.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" @@ -27,7 +27,8 @@ */ int pmac_process(pmac_state *pmac, const unsigned char *in, unsigned long inlen) { - int err, n, x; + int err, n; + unsigned long x; unsigned char Z[MAXBLOCKSIZE]; LTC_ARGCHK(pmac != NULL); @@ -41,15 +42,33 @@ int pmac_process(pmac_state *pmac, const unsigned char *in, unsigned long inlen) return CRYPT_INVALID_ARG; } +#ifdef LTC_FAST + if (pmac->buflen == 0 && inlen > 16) { + unsigned long y; + for (x = 0; x < (inlen - 16); x += 16) { + pmac_shift_xor(pmac); + for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) { + *((LTC_FAST_TYPE*)(&Z[y])) = *((LTC_FAST_TYPE*)(&in[y])) ^ *((LTC_FAST_TYPE*)(&pmac->Li[y])); + } + cipher_descriptor[pmac->cipher_idx].ecb_encrypt(Z, Z, &pmac->key); + for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) { + *((LTC_FAST_TYPE*)(&pmac->checksum[y])) ^= *((LTC_FAST_TYPE*)(&Z[y])); + } + in += 16; + } + inlen -= x; + } +#endif + while (inlen != 0) { /* ok if the block is full we xor in prev, encrypt and replace prev */ if (pmac->buflen == pmac->block_len) { pmac_shift_xor(pmac); - for (x = 0; x < pmac->block_len; x++) { - Z[x] = pmac->Li[x] ^ pmac->block[x]; + for (x = 0; x < (unsigned long)pmac->block_len; x++) { + Z[x] = pmac->Li[x] ^ pmac->block[x]; } cipher_descriptor[pmac->cipher_idx].ecb_encrypt(Z, Z, &pmac->key); - for (x = 0; x < pmac->block_len; x++) { + for (x = 0; x < (unsigned long)pmac->block_len; x++) { pmac->checksum[x] ^= Z[x]; } pmac->buflen = 0; diff --git a/src/mac/pmac/pmac_shift_xor.c b/src/mac/pmac/pmac_shift_xor.c index 5c9ab96..18c6141 100644 --- a/src/mac/pmac/pmac_shift_xor.c +++ b/src/mac/pmac/pmac_shift_xor.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" @@ -25,9 +25,16 @@ void pmac_shift_xor(pmac_state *pmac) { int x, y; y = pmac_ntz(pmac->block_index++); +#ifdef LTC_FAST + for (x = 0; x < pmac->block_len; x += sizeof(LTC_FAST_TYPE)) { + *((LTC_FAST_TYPE*)((unsigned char *)pmac->Li + x)) ^= + *((LTC_FAST_TYPE*)((unsigned char *)pmac->Ls[y] + x)); + } +#else for (x = 0; x < pmac->block_len; x++) { pmac->Li[x] ^= pmac->Ls[y][x]; } +#endif } #endif diff --git a/src/mac/pmac/pmac_test.c b/src/mac/pmac/pmac_test.c index 08cc9b3..6c610f9 100644 --- a/src/mac/pmac/pmac_test.c +++ b/src/mac/pmac/pmac_test.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/misc/base64/base64_decode.c b/src/misc/base64/base64_decode.c index 5c220ee..ac6db57 100644 --- a/src/misc/base64/base64_decode.c +++ b/src/misc/base64/base64_decode.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" @@ -65,8 +65,20 @@ int base64_decode(const unsigned char *in, unsigned long inlen, for (x = y = z = t = 0; x < inlen; x++) { c = map[in[x]&0xFF]; if (c == 255) continue; - if (c == 254) { c = 0; g--; } + /* the final = symbols are read and used to trim the remaining bytes */ + if (c == 254) { + c = 0; + /* prevent g < 0 which would potentially allow an overflow later */ + if (--g < 0) { + return CRYPT_INVALID_PACKET; + } + } else if (g != 3) { + /* we only allow = to be at the end */ + return CRYPT_INVALID_PACKET; + } + t = (t<<6)|c; + if (++y == 4) { if (z + g > *outlen) { return CRYPT_BUFFER_OVERFLOW; diff --git a/src/misc/base64/base64_encode.c b/src/misc/base64/base64_encode.c index 85b5a17..047980c 100644 --- a/src/misc/base64/base64_encode.c +++ b/src/misc/base64/base64_encode.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/misc/burn_stack.c b/src/misc/burn_stack.c index 0724154..3bc69ab 100644 --- a/src/misc/burn_stack.c +++ b/src/misc/burn_stack.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/misc/crypt/crypt.c b/src/misc/crypt/crypt.c index 6726046..83f1414 100644 --- a/src/misc/crypt/crypt.c +++ b/src/misc/crypt/crypt.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" @@ -179,6 +179,9 @@ const char *crypt_build_settings = #if defined(PMAC) " PMAC\n" #endif +#if defined(PELICAN) + " PELICAN\n" +#endif "\nENC + AUTH modes:\n" #if defined(EAX_MODE) @@ -187,6 +190,16 @@ const char *crypt_build_settings = #if defined(OCB_MODE) " OCB_MODE\n" #endif +#if defined(CCM_MODE) + " CCM_MODE\n" +#endif +#if defined(GCM_MODE) + " GCM_MODE " +#endif +#if defined(GCM_TABLES) + " (GCM_TABLES) " +#endif + "\n" "\nPRNG:\n" @@ -270,6 +283,18 @@ const char *crypt_build_settings = #endif #if defined(LTC_DER) " LTC_DER " +#endif +#if defined(LTC_FAST) + " LTC_FAST " +#endif +#if defined(LTC_NO_FAST) + " LTC_NO_FAST " +#endif +#if defined(LTC_NO_BSWAP) + " LTC_NO_BSWAP " +#endif +#if defined(LTC_NO_ASM) + " LTC_NO_ASM " #endif "\n" "\n\n\n" diff --git a/src/misc/crypt/crypt_argchk.c b/src/misc/crypt/crypt_argchk.c index b44d012..d345c8d 100644 --- a/src/misc/crypt/crypt_argchk.c +++ b/src/misc/crypt/crypt_argchk.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" #include diff --git a/src/misc/crypt/crypt_cipher_descriptor.c b/src/misc/crypt/crypt_cipher_descriptor.c index 99091bf..e274449 100644 --- a/src/misc/crypt/crypt_cipher_descriptor.c +++ b/src/misc/crypt/crypt_cipher_descriptor.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" @@ -15,5 +15,7 @@ Stores the cipher descriptor table, Tom St Denis */ -struct ltc_cipher_descriptor cipher_descriptor[TAB_SIZE]; +struct ltc_cipher_descriptor cipher_descriptor[TAB_SIZE] = { +{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } + }; diff --git a/src/misc/crypt/crypt_cipher_is_valid.c b/src/misc/crypt/crypt_cipher_is_valid.c index f730b54..b179402 100644 --- a/src/misc/crypt/crypt_cipher_is_valid.c +++ b/src/misc/crypt/crypt_cipher_is_valid.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/misc/crypt/crypt_find_cipher.c b/src/misc/crypt/crypt_find_cipher.c index 661e0ae..b83109c 100644 --- a/src/misc/crypt/crypt_find_cipher.c +++ b/src/misc/crypt/crypt_find_cipher.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/misc/crypt/crypt_find_cipher_any.c b/src/misc/crypt/crypt_find_cipher_any.c index 880b082..42e59c0 100644 --- a/src/misc/crypt/crypt_find_cipher_any.c +++ b/src/misc/crypt/crypt_find_cipher_any.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/misc/crypt/crypt_find_cipher_id.c b/src/misc/crypt/crypt_find_cipher_id.c index 422eef7..986baf5 100644 --- a/src/misc/crypt/crypt_find_cipher_id.c +++ b/src/misc/crypt/crypt_find_cipher_id.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/misc/crypt/crypt_find_hash.c b/src/misc/crypt/crypt_find_hash.c index e7eb9ee..d66201c 100644 --- a/src/misc/crypt/crypt_find_hash.c +++ b/src/misc/crypt/crypt_find_hash.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/misc/crypt/crypt_find_hash_any.c b/src/misc/crypt/crypt_find_hash_any.c index a2650ec..0d6d430 100644 --- a/src/misc/crypt/crypt_find_hash_any.c +++ b/src/misc/crypt/crypt_find_hash_any.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/misc/crypt/crypt_find_hash_id.c b/src/misc/crypt/crypt_find_hash_id.c index fbd965a..8628d53 100644 --- a/src/misc/crypt/crypt_find_hash_id.c +++ b/src/misc/crypt/crypt_find_hash_id.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/misc/crypt/crypt_find_prng.c b/src/misc/crypt/crypt_find_prng.c index cac1317..c01a023 100644 --- a/src/misc/crypt/crypt_find_prng.c +++ b/src/misc/crypt/crypt_find_prng.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/misc/crypt/crypt_hash_descriptor.c b/src/misc/crypt/crypt_hash_descriptor.c index e06cbf0..cbd6d03 100644 --- a/src/misc/crypt/crypt_hash_descriptor.c +++ b/src/misc/crypt/crypt_hash_descriptor.c @@ -6,14 +6,15 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" /** - @file crypt_hash_decriptor.c + @file crypt_hash_descriptor.c Stores the hash descriptor table, Tom St Denis */ -struct ltc_hash_descriptor hash_descriptor[TAB_SIZE]; - +struct ltc_hash_descriptor hash_descriptor[TAB_SIZE] = { +{ NULL, 0, 0, 0, { 0 }, 0, NULL, NULL, NULL, NULL } +}; diff --git a/src/misc/crypt/crypt_hash_is_valid.c b/src/misc/crypt/crypt_hash_is_valid.c index 8ea88a0..c9784b8 100644 --- a/src/misc/crypt/crypt_hash_is_valid.c +++ b/src/misc/crypt/crypt_hash_is_valid.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/misc/crypt/crypt_prng_descriptor.c b/src/misc/crypt/crypt_prng_descriptor.c index 6f496da..8a99510 100644 --- a/src/misc/crypt/crypt_prng_descriptor.c +++ b/src/misc/crypt/crypt_prng_descriptor.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" @@ -14,4 +14,6 @@ @file crypt_prng_descriptor.c Stores the PRNG descriptors, Tom St Denis */ -struct ltc_prng_descriptor prng_descriptor[TAB_SIZE]; +struct ltc_prng_descriptor prng_descriptor[TAB_SIZE] = { +{ NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } +}; diff --git a/src/misc/crypt/crypt_prng_is_valid.c b/src/misc/crypt/crypt_prng_is_valid.c index 8634e94..7795bbb 100644 --- a/src/misc/crypt/crypt_prng_is_valid.c +++ b/src/misc/crypt/crypt_prng_is_valid.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/misc/crypt/crypt_register_cipher.c b/src/misc/crypt/crypt_register_cipher.c index c1fe8f0..74349e6 100644 --- a/src/misc/crypt/crypt_register_cipher.c +++ b/src/misc/crypt/crypt_register_cipher.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/misc/crypt/crypt_register_hash.c b/src/misc/crypt/crypt_register_hash.c index 8d05e42..d5cf5b8 100644 --- a/src/misc/crypt/crypt_register_hash.c +++ b/src/misc/crypt/crypt_register_hash.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/misc/crypt/crypt_register_prng.c b/src/misc/crypt/crypt_register_prng.c index 50ff229..6a1be77 100644 --- a/src/misc/crypt/crypt_register_prng.c +++ b/src/misc/crypt/crypt_register_prng.c @@ -6,12 +6,12 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" /** - @file register_prng.c + @file crypt_register_prng.c Register a PRNG, Tom St Denis */ diff --git a/src/misc/crypt/crypt_unregister_cipher.c b/src/misc/crypt/crypt_unregister_cipher.c index 309e08a..0511de5 100644 --- a/src/misc/crypt/crypt_unregister_cipher.c +++ b/src/misc/crypt/crypt_unregister_cipher.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/misc/crypt/crypt_unregister_hash.c b/src/misc/crypt/crypt_unregister_hash.c index aef522d..25e36f2 100644 --- a/src/misc/crypt/crypt_unregister_hash.c +++ b/src/misc/crypt/crypt_unregister_hash.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/misc/crypt/crypt_unregister_prng.c b/src/misc/crypt/crypt_unregister_prng.c index fafa9b6..55cc554 100644 --- a/src/misc/crypt/crypt_unregister_prng.c +++ b/src/misc/crypt/crypt_unregister_prng.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/misc/error_to_string.c b/src/misc/error_to_string.c index 5a7e0f4..3a325a2 100644 --- a/src/misc/error_to_string.c +++ b/src/misc/error_to_string.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/misc/mpi/is_prime.c b/src/misc/mpi/is_prime.c index 4f52323..f58391f 100644 --- a/src/misc/mpi/is_prime.c +++ b/src/misc/mpi/is_prime.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/misc/mpi/mpi.c b/src/misc/mpi/mpi.c index e5664e6..ba3a7ed 100644 --- a/src/misc/mpi/mpi.c +++ b/src/misc/mpi/mpi.c @@ -13,7 +13,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ static const struct { @@ -60,7 +60,7 @@ char *mp_error_to_string(int code) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* computes the modular inverse via binary extended euclidean algorithm, @@ -69,8 +69,7 @@ char *mp_error_to_string(int code) * 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 -fast_mp_invmod (mp_int * a, mp_int * b, mp_int * c) +int fast_mp_invmod (mp_int * a, mp_int * b, mp_int * c) { mp_int x, y, u, v, B, D; int res, neg; @@ -91,7 +90,7 @@ fast_mp_invmod (mp_int * a, mp_int * b, mp_int * c) } /* we need y = |a| */ - if ((res = mp_abs (a, &y)) != MP_OKAY) { + if ((res = mp_mod (a, b, &y)) != MP_OKAY) { goto LBL_ERR; } @@ -209,7 +208,7 @@ LBL_ERR:mp_clear_multi (&x, &y, &u, &v, &B, &D, NULL); * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* computes xR**-1 == x (mod N) via Montgomery Reduction @@ -220,8 +219,7 @@ LBL_ERR:mp_clear_multi (&x, &y, &u, &v, &B, &D, NULL); * * Based on Algorithm 14.32 on pp.601 of HAC. */ -int -fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) +int fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) { int ix, res, olduse; mp_word W[MP_WARRAY]; @@ -382,7 +380,7 @@ fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* Fast (comba) multiplier @@ -401,15 +399,14 @@ fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) * Based on Algorithm 14.12 on pp.595 of HAC. * */ -int -fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) +int fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) { int olduse, res, pa, ix, iz; mp_digit W[MP_WARRAY]; register mp_word _W; /* grow the destination as required */ - if (c->alloc <= digs) { + if (c->alloc < digs) { if ((res = mp_grow (c, digs)) != MP_OKAY) { return res; } @@ -433,7 +430,7 @@ fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) tmpx = a->dp + tx; tmpy = b->dp + ty; - /* this is the number of times the loop will iterrate, essentially its + /* this is the number of times the loop will iterrate, essentially while (tx++ < a->used && ty-- >= 0) { ... } */ iy = MIN(a->used-tx, ty+1); @@ -451,16 +448,16 @@ fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) } /* store final carry */ - W[ix] = _W; + W[ix] = (mp_digit)(_W & MP_MASK); /* setup dest */ olduse = c->used; - c->used = digs; + c->used = pa; { register mp_digit *tmpc; tmpc = c->dp; - for (ix = 0; ix < digs; ix++) { + for (ix = 0; ix < pa+1; ix++) { /* now extract the previous digit [below the carry] */ *tmpc++ = W[ix]; } @@ -492,7 +489,7 @@ fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* this is a modified version of fast_s_mul_digs that only produces @@ -504,8 +501,7 @@ fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) * * Based on Algorithm 14.12 on pp.595 of HAC. */ -int -fast_s_mp_mul_high_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 olduse, res, pa, ix, iz; mp_digit W[MP_WARRAY]; @@ -513,7 +509,7 @@ fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs) /* grow the destination as required */ pa = a->used + b->used; - if (c->alloc <= pa) { + if (c->alloc < pa) { if ((res = mp_grow (c, pa)) != MP_OKAY) { return res; } @@ -552,7 +548,7 @@ fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs) } /* store final carry */ - W[ix] = _W; + W[ix] = (mp_digit)(_W & MP_MASK); /* setup dest */ olduse = c->used; @@ -594,36 +590,17 @@ fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ -/* fast squaring - * - * This is the comba method where the columns of the product - * are computed first then the carries are computed. This - * has the effect of making a very simple inner loop that - * is executed the most - * - * W2 represents the outer products and W the inner. - * - * A further optimizations is made because the inner - * products are of the form "A * B * 2". The *2 part does - * not need to be computed until the end which is good - * because 64-bit shifts are slow! - * - * 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 + * 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) @@ -634,7 +611,7 @@ int fast_s_mp_sqr (mp_int * a, mp_int * b) /* grow the destination as required */ pa = a->used + a->used; - if (b->alloc <= pa) { + if (b->alloc < pa) { if ((res = mp_grow (b, pa)) != MP_OKAY) { return res; } @@ -658,7 +635,7 @@ int fast_s_mp_sqr (mp_int * a, mp_int * b) tmpx = a->dp + tx; tmpy = a->dp + ty; - /* this is the number of times the loop will iterrate, essentially its + /* this is the number of times the loop will iterrate, essentially while (tx++ < a->used && ty-- >= 0) { ... } */ iy = MIN(a->used-tx, ty+1); @@ -683,7 +660,7 @@ int fast_s_mp_sqr (mp_int * a, mp_int * b) } /* store it */ - W[ix] = _W; + W[ix] = (mp_digit)(_W & MP_MASK); /* make next carry */ W1 = _W >> ((mp_word)DIGIT_BIT); @@ -727,7 +704,7 @@ int fast_s_mp_sqr (mp_int * a, mp_int * b) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* computes a = 2**b @@ -775,7 +752,7 @@ mp_2expt (mp_int * a, int b) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* b = |a| @@ -818,7 +795,7 @@ mp_abs (mp_int * a, mp_int * b) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* high level addition (handles signs) */ @@ -871,7 +848,7 @@ int mp_add (mp_int * a, mp_int * b, mp_int * c) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* single digit addition */ @@ -980,7 +957,7 @@ mp_add_d (mp_int * a, mp_digit b, mp_int * c) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* d = a + b (mod c) */ @@ -1021,7 +998,7 @@ mp_addmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* AND two ints together */ @@ -1078,7 +1055,7 @@ mp_and (mp_int * a, mp_int * b, mp_int * c) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* trim unused digits @@ -1122,7 +1099,7 @@ mp_clamp (mp_int * a) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* clear one (frees) */ @@ -1166,7 +1143,7 @@ mp_clear (mp_int * a) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ #include @@ -1200,7 +1177,7 @@ void mp_clear_multi(mp_int *mp, ...) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* compare two ints (signed)*/ @@ -1243,7 +1220,7 @@ mp_cmp (mp_int * a, mp_int * b) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* compare a digit */ @@ -1287,7 +1264,7 @@ int mp_cmp_d(mp_int * a, mp_digit b) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* compare maginitude of two ints (unsigned) */ @@ -1342,7 +1319,7 @@ int mp_cmp_mag (mp_int * a, mp_int * b) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ static const int lnz[16] = { @@ -1395,7 +1372,7 @@ int mp_cnt_lsb(mp_int *a) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* copy, b = a */ @@ -1463,7 +1440,7 @@ mp_copy (mp_int * a, mp_int * b) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* returns the number of bits in an int */ @@ -1508,7 +1485,7 @@ mp_count_bits (mp_int * a) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ #ifdef BN_MP_DIV_SMALL @@ -1800,7 +1777,7 @@ LBL_Q:mp_clear (&q); * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* b = a/2 */ @@ -1868,7 +1845,7 @@ int mp_div_2(mp_int * a, mp_int * b) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* shift right by a certain bit count (store quotient in c, optional remainder in d) */ @@ -1965,7 +1942,7 @@ int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* divide by three (based on routine from MPI and the GMP manual) */ @@ -2044,7 +2021,7 @@ mp_div_3 (mp_int * a, mp_int *c, mp_digit * d) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ static int s_is_power_of_two(mp_digit b, int *p) @@ -2154,7 +2131,7 @@ int mp_div_d (mp_int * a, mp_digit b, mp_int * c, mp_digit * d) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* determines if a number is a valid DR modulus */ @@ -2197,7 +2174,7 @@ int mp_dr_is_modulus(mp_int *a) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* reduce "x" in place modulo "n" using the Diminished Radix algorithm. @@ -2205,7 +2182,7 @@ int mp_dr_is_modulus(mp_int *a) * Based on algorithm from the paper * * "Generating Efficient Primes for Discrete Log Cryptosystems" - * Chae Hoon Lim, Pil Loong Lee, + * Chae Hoon Lim, Pil Joong Lee, * POSTECH Information Research Laboratories * * The modulus must be of a special format [see manual] @@ -2291,7 +2268,7 @@ top: * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* determines the setup value */ @@ -2323,7 +2300,7 @@ void mp_dr_setup(mp_int *a, mp_digit *d) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* swap the elements of two integers, for cases where you can't simply swap the @@ -2357,7 +2334,7 @@ mp_exch (mp_int * a, mp_int * b) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* calculate c = a**b using a square-multiply algorithm */ @@ -2414,7 +2391,7 @@ int mp_expt_d (mp_int * a, mp_digit b, mp_int * c) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ @@ -2467,21 +2444,29 @@ int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) #endif } +/* modified diminished radix reduction */ +#if defined(BN_MP_REDUCE_IS_2K_L_C) && defined(BN_MP_REDUCE_2K_L_C) + if (mp_reduce_is_2k_l(P) == MP_YES) { + return s_mp_exptmod(G, X, P, Y, 1); + } +#endif + #ifdef BN_MP_DR_IS_MODULUS_C /* is it a DR modulus? */ dr = mp_dr_is_modulus(P); #else + /* default to no */ dr = 0; #endif #ifdef BN_MP_REDUCE_IS_2K_C - /* if not, is it a uDR modulus? */ + /* if not, is it a unrestricted DR modulus? */ if (dr == 0) { dr = mp_reduce_is_2k(P) << 1; } #endif - /* if the modulus is odd or dr != 0 use the fast method */ + /* if the modulus is odd or dr != 0 use the montgomery method */ #ifdef BN_MP_EXPTMOD_FAST_C if (mp_isodd (P) == 1 || dr != 0) { return mp_exptmod_fast (G, X, P, Y, dr); @@ -2489,7 +2474,7 @@ int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) #endif #ifdef BN_S_MP_EXPTMOD_C /* otherwise use the generic Barrett reduction technique */ - return s_mp_exptmod (G, X, P, Y); + return s_mp_exptmod (G, X, P, Y, 0); #else /* no exptmod for evens */ return MP_VAL; @@ -2518,7 +2503,7 @@ int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* computes Y == G**X mod P, HAC pp.616, Algorithm 14.85 @@ -2535,8 +2520,7 @@ int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) #define TAB_SIZE 256 #endif -int -mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) +int mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) { mp_int M[TAB_SIZE], res; mp_digit buf, mp; @@ -2840,7 +2824,7 @@ LBL_M: * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* Extended euclidean algorithm of (a, b) produces @@ -2887,6 +2871,13 @@ int mp_exteuclid(mp_int *a, mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3) if ((err = mp_copy(&t3, &v3)) != MP_OKAY) { goto _ERR; } } + /* make sure U3 >= 0 */ + if (u3.sign == MP_NEG) { + mp_neg(&u1, &u1); + mp_neg(&u2, &u2); + mp_neg(&u3, &u3); + } + /* copy result out */ if (U1 != NULL) { mp_exch(U1, &u1); } if (U2 != NULL) { mp_exch(U2, &u2); } @@ -2915,7 +2906,7 @@ _ERR: mp_clear_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* read a bigint from a file stream in ASCII */ @@ -2982,7 +2973,7 @@ int mp_fread(mp_int *a, int radix, FILE *stream) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ int mp_fwrite(mp_int *a, int radix, FILE *stream) @@ -3034,7 +3025,7 @@ int mp_fwrite(mp_int *a, int radix, FILE *stream) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* Greatest Common Divisor using the binary method */ @@ -3147,7 +3138,7 @@ LBL_U:mp_clear (&v); * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* get the lower 32-bits of an mp_int */ @@ -3192,7 +3183,7 @@ unsigned long mp_get_int(mp_int * a) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* grow as required */ @@ -3249,7 +3240,7 @@ int mp_grow (mp_int * a, int size) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* init a new mp_int */ @@ -3295,7 +3286,7 @@ int mp_init (mp_int * a) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* creates "a" then copies b into it */ @@ -3327,7 +3318,7 @@ int mp_init_copy (mp_int * a, mp_int * b) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ #include @@ -3386,7 +3377,7 @@ int mp_init_multi(mp_int *mp, ...) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* initialize and set a digit */ @@ -3418,7 +3409,7 @@ int mp_init_set (mp_int * a, mp_digit b) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* initialize and set a digit */ @@ -3449,7 +3440,7 @@ int mp_init_set_int (mp_int * a, unsigned long b) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* init an mp_init for a given size */ @@ -3497,7 +3488,7 @@ int mp_init_size (mp_int * a, int size) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* hac 14.61, pp608 */ @@ -3540,7 +3531,7 @@ int mp_invmod (mp_int * a, mp_int * b, mp_int * c) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* hac 14.61, pp608 */ @@ -3561,8 +3552,8 @@ int mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c) } /* x = a, y = b */ - if ((res = mp_copy (a, &x)) != MP_OKAY) { - goto LBL_ERR; + if ((res = mp_mod(a, b, &x)) != MP_OKAY) { + goto LBL_ERR; } if ((res = mp_copy (b, &y)) != MP_OKAY) { goto LBL_ERR; @@ -3715,7 +3706,7 @@ LBL_ERR:mp_clear_multi (&x, &y, &u, &v, &A, &B, &C, &D, NULL); * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* Check if remainders are possible squares - fast exclude non-squares */ @@ -3824,7 +3815,7 @@ ERR:mp_clear(&t); * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* computes the jacobi c = (a | n) (or Legendre if n is prime) @@ -3929,7 +3920,7 @@ LBL_A1:mp_clear (&a1); * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* c = |a| * |b| using Karatsuba Multiplication using @@ -4096,7 +4087,7 @@ ERR: * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* Karatsuba squaring, computes b = a*a using three @@ -4217,7 +4208,7 @@ ERR: * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* computes least common multiple as |a*b|/(a, b) */ @@ -4277,7 +4268,7 @@ LBL_T: * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* shift left a certain amount of digits */ @@ -4344,7 +4335,7 @@ int mp_lshd (mp_int * a, int b) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* c = a mod b, 0 <= c < b */ @@ -4392,7 +4383,7 @@ mp_mod (mp_int * a, mp_int * b, mp_int * c) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* calc a value mod 2**b */ @@ -4447,7 +4438,7 @@ mp_mod_2d (mp_int * a, int b, mp_int * c) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ int @@ -4474,7 +4465,7 @@ mp_mod_d (mp_int * a, mp_digit b, mp_digit * c) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* @@ -4490,7 +4481,6 @@ int mp_montgomery_calc_normalization (mp_int * a, mp_int * b) /* how many bits of last digit does b use */ bits = mp_count_bits (b) % DIGIT_BIT; - if (b->used > 1) { if ((res = mp_2expt (a, (b->used - 1) * DIGIT_BIT + bits - 1)) != MP_OKAY) { return res; @@ -4534,7 +4524,7 @@ int mp_montgomery_calc_normalization (mp_int * a, mp_int * b) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* computes xR**-1 == x (mod N) via Montgomery Reduction */ @@ -4652,7 +4642,7 @@ mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* setups the montgomery reduction stuff */ @@ -4711,7 +4701,7 @@ mp_montgomery_setup (mp_int * n, mp_digit * rho) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* high level multiplication (handles sign) */ @@ -4777,7 +4767,7 @@ int mp_mul (mp_int * a, mp_int * b, mp_int * c) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* b = a*2 */ @@ -4859,7 +4849,7 @@ int mp_mul_2(mp_int * a, mp_int * b) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* shift left by a certain bit count */ @@ -4944,7 +4934,7 @@ int mp_mul_2d (mp_int * a, int b, mp_int * c) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* multiply by a digit */ @@ -4989,8 +4979,9 @@ mp_mul_d (mp_int * a, mp_digit b, mp_int * c) u = (mp_digit) (r >> ((mp_word) DIGIT_BIT)); } - /* store final carry [if any] */ + /* store final carry [if any] and increment ix offset */ *tmpc++ = u; + ++ix; /* now zero digits above the top */ while (ix++ < olduse) { @@ -5022,7 +5013,7 @@ mp_mul_d (mp_int * a, mp_digit b, mp_int * c) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* d = a * b (mod c) */ @@ -5063,7 +5054,7 @@ mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* find the n'th root of an integer @@ -5195,19 +5186,25 @@ LBL_T1:mp_clear (&t1); * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* b = -a */ int mp_neg (mp_int * a, mp_int * b) { int res; - if ((res = mp_copy (a, b)) != MP_OKAY) { - return res; + if (a != b) { + if ((res = mp_copy (a, b)) != MP_OKAY) { + return res; + } } + if (mp_iszero(b) != MP_YES) { b->sign = (a->sign == MP_ZPOS) ? MP_NEG : MP_ZPOS; + } else { + b->sign = MP_ZPOS; } + return MP_OKAY; } #endif @@ -5229,7 +5226,7 @@ int mp_neg (mp_int * a, mp_int * b) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* OR two ints together */ @@ -5279,7 +5276,7 @@ int mp_or (mp_int * a, mp_int * b, mp_int * c) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* performs one Fermat test. @@ -5341,7 +5338,7 @@ LBL_T:mp_clear (&t); * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* determines if an integers is divisible by one @@ -5391,7 +5388,7 @@ int mp_prime_is_divisible (mp_int * a, int *result) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* performs a variable number of rounds of Miller-Rabin @@ -5474,7 +5471,7 @@ LBL_B:mp_clear (&b); * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* Miller-Rabin test of "a" to the base of "b" as described in @@ -5577,7 +5574,7 @@ LBL_N1:mp_clear (&n1); * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* finds the next prime after the number "a" using "t" trials @@ -5747,7 +5744,7 @@ LBL_ERR: * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ @@ -5799,7 +5796,7 @@ int mp_prime_rabin_miller_trials(int size) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* makes a truly random prime of a given size (bits), @@ -5847,12 +5844,10 @@ int mp_prime_random_ex(mp_int *a, int t, int size, int flags, ltm_prime_callback /* calc the maskOR_msb */ maskOR_msb = 0; - maskOR_msb_offset = ((size&7)==1)?1:0; + maskOR_msb_offset = ((size & 7) == 1) ? 1 : 0; if (flags & LTM_PRIME_2MSB_ON) { - maskOR_msb |= 1 << ((size - 2) & 7); - } else if (flags & LTM_PRIME_2MSB_OFF) { - maskAND &= ~(1 << ((size - 2) & 7)); - } + maskOR_msb |= 0x80 >> ((9 - size) & 7); + } /* get the maskOR_lsb */ maskOR_lsb = 1; @@ -5926,7 +5921,7 @@ error: * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* returns size of ASCII reprensentation */ @@ -5949,22 +5944,29 @@ int mp_radix_size (mp_int * a, int radix, int *size) return MP_VAL; } - /* init a copy of the input */ - if ((res = mp_init_copy (&t, a)) != MP_OKAY) { - return res; + if (mp_iszero(a) == MP_YES) { + *size = 2; + return MP_OKAY; } /* digs is the digit count */ digs = 0; /* if it's negative add one for the sign */ - if (t.sign == MP_NEG) { + if (a->sign == MP_NEG) { ++digs; - t.sign = MP_ZPOS; } + /* init a copy of the input */ + if ((res = mp_init_copy (&t, a)) != MP_OKAY) { + return res; + } + + /* force temp to positive */ + t.sign = MP_ZPOS; + /* fetch out all of the digits */ - while (mp_iszero (&t) == 0) { + while (mp_iszero (&t) == MP_NO) { if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) { mp_clear (&t); return res; @@ -5997,7 +5999,7 @@ int mp_radix_size (mp_int * a, int radix, int *size) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* chars used in radix conversions */ @@ -6021,7 +6023,7 @@ const char *mp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrs * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* makes a pseudo-random int of a given size */ @@ -6038,14 +6040,14 @@ mp_rand (mp_int * a, int digits) /* first place a random non-zero digit */ do { - d = ((mp_digit) abs (rand ())); + d = ((mp_digit) abs (rand ())) & MP_MASK; } while (d == 0); if ((res = mp_add_d (a, d, a)) != MP_OKAY) { return res; } - while (digits-- > 0) { + while (--digits > 0) { if ((res = mp_lshd (a, 1)) != MP_OKAY) { return res; } @@ -6076,11 +6078,11 @@ mp_rand (mp_int * a, int digits) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* read a string [ASCII] in a given radix */ -int mp_read_radix (mp_int * a, char *str, int radix) +int mp_read_radix (mp_int * a, const char *str, int radix) { int y, res, neg; char ch; @@ -6158,12 +6160,11 @@ int mp_read_radix (mp_int * a, char *str, int radix) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* read signed bin, big endian, first byte is 0==positive or 1==negative */ -int -mp_read_signed_bin (mp_int * a, unsigned char *b, int c) +int mp_read_signed_bin (mp_int * a, const unsigned char *b, int c) { int res; @@ -6200,12 +6201,11 @@ mp_read_signed_bin (mp_int * a, unsigned char *b, int c) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* reads a unsigned char array, assumes the msb is stored first [big endian] */ -int -mp_read_unsigned_bin (mp_int * a, unsigned char *b, int c) +int mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c) { int res; @@ -6256,15 +6256,14 @@ mp_read_unsigned_bin (mp_int * a, unsigned char *b, int c) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* reduces x mod m, assumes 0 < x < m**2, mu is * precomputed via mp_reduce_setup. * From HAC pp.604 Algorithm 14.42 */ -int -mp_reduce (mp_int * x, mp_int * m, mp_int * mu) +int mp_reduce (mp_int * x, mp_int * m, mp_int * mu) { mp_int q; int res, um = m->used; @@ -6284,11 +6283,11 @@ mp_reduce (mp_int * x, mp_int * m, mp_int * mu) } } else { #ifdef BN_S_MP_MUL_HIGH_DIGS_C - if ((res = s_mp_mul_high_digs (&q, mu, &q, um - 1)) != MP_OKAY) { + if ((res = s_mp_mul_high_digs (&q, mu, &q, um)) != 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) { + if ((res = fast_s_mp_mul_high_digs (&q, mu, &q, um)) != MP_OKAY) { goto CLEANUP; } #else @@ -6357,12 +6356,11 @@ CLEANUP: * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* reduces a modulo n where n is of the form 2**p - d */ -int -mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d) +int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d) { mp_int q; int p, res; @@ -6404,6 +6402,68 @@ ERR: /* End: bn_mp_reduce_2k.c */ +/* Start: bn_mp_reduce_2k_l.c */ +#include +#ifdef BN_MP_REDUCE_2K_L_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@gmail.com, http://math.libtomcrypt.org + */ + +/* reduces a modulo n where n is of the form 2**p - d + This differs from reduce_2k since "d" can be larger + than a single digit. +*/ +int mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d) +{ + mp_int q; + int p, res; + + if ((res = mp_init(&q)) != MP_OKAY) { + return res; + } + + p = mp_count_bits(n); +top: + /* q = a/2**p, a = a mod 2**p */ + if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) { + goto ERR; + } + + /* q = q * d */ + if ((res = mp_mul(&q, d, &q)) != MP_OKAY) { + goto ERR; + } + + /* a = a + q */ + if ((res = s_mp_add(a, &q, a)) != MP_OKAY) { + goto ERR; + } + + if (mp_cmp_mag(a, n) != MP_LT) { + s_mp_sub(a, n, a); + goto top; + } + +ERR: + mp_clear(&q); + return res; +} + +#endif + +/* End: bn_mp_reduce_2k_l.c */ + /* Start: bn_mp_reduce_2k_setup.c */ #include #ifdef BN_MP_REDUCE_2K_SETUP_C @@ -6419,12 +6479,11 @@ ERR: * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* determines the setup value */ -int -mp_reduce_2k_setup(mp_int *a, mp_digit *d) +int mp_reduce_2k_setup(mp_int *a, mp_digit *d) { int res, p; mp_int tmp; @@ -6452,6 +6511,50 @@ mp_reduce_2k_setup(mp_int *a, mp_digit *d) /* End: bn_mp_reduce_2k_setup.c */ +/* Start: bn_mp_reduce_2k_setup_l.c */ +#include +#ifdef BN_MP_REDUCE_2K_SETUP_L_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@gmail.com, http://math.libtomcrypt.org + */ + +/* determines the setup value */ +int mp_reduce_2k_setup_l(mp_int *a, mp_int *d) +{ + int res; + mp_int tmp; + + if ((res = mp_init(&tmp)) != MP_OKAY) { + return res; + } + + if ((res = mp_2expt(&tmp, mp_count_bits(a))) != MP_OKAY) { + goto ERR; + } + + if ((res = s_mp_sub(&tmp, a, d)) != MP_OKAY) { + goto ERR; + } + +ERR: + mp_clear(&tmp); + return res; +} +#endif + +/* End: bn_mp_reduce_2k_setup_l.c */ + /* Start: bn_mp_reduce_is_2k.c */ #include #ifdef BN_MP_REDUCE_IS_2K_C @@ -6467,7 +6570,7 @@ mp_reduce_2k_setup(mp_int *a, mp_digit *d) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* determines if mp_reduce_2k can be used */ @@ -6477,9 +6580,9 @@ int mp_reduce_is_2k(mp_int *a) mp_digit iz; if (a->used == 0) { - return 0; + return MP_NO; } else if (a->used == 1) { - return 1; + return MP_YES; } else if (a->used > 1) { iy = mp_count_bits(a); iz = 1; @@ -6488,7 +6591,7 @@ int mp_reduce_is_2k(mp_int *a) /* Test every bit from the second digit up, must be 1 */ for (ix = DIGIT_BIT; ix < iy; ix++) { if ((a->dp[iw] & iz) == 0) { - return 0; + return MP_NO; } iz <<= 1; if (iz > (mp_digit)MP_MASK) { @@ -6497,13 +6600,57 @@ int mp_reduce_is_2k(mp_int *a) } } } - return 1; + return MP_YES; } #endif /* End: bn_mp_reduce_is_2k.c */ +/* Start: bn_mp_reduce_is_2k_l.c */ +#include +#ifdef BN_MP_REDUCE_IS_2K_L_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@gmail.com, http://math.libtomcrypt.org + */ + +/* determines if reduce_2k_l can be used */ +int mp_reduce_is_2k_l(mp_int *a) +{ + int ix, iy; + + if (a->used == 0) { + return MP_NO; + } else if (a->used == 1) { + return MP_YES; + } else if (a->used > 1) { + /* if more than half of the digits are -1 we're sold */ + for (iy = ix = 0; ix < a->used; ix++) { + if (a->dp[ix] == MP_MASK) { + ++iy; + } + } + return (iy >= (a->used/2)) ? MP_YES : MP_NO; + + } + return MP_NO; +} + +#endif + +/* End: bn_mp_reduce_is_2k_l.c */ + /* Start: bn_mp_reduce_setup.c */ #include #ifdef BN_MP_REDUCE_SETUP_C @@ -6519,7 +6666,7 @@ int mp_reduce_is_2k(mp_int *a) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* pre-calculate the value required for Barrett reduction @@ -6553,7 +6700,7 @@ int mp_reduce_setup (mp_int * a, mp_int * b) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* shift right a certain amount of digits */ @@ -6625,7 +6772,7 @@ void mp_rshd (mp_int * a, int b) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* set to a digit */ @@ -6654,7 +6801,7 @@ void mp_set (mp_int * a, mp_digit b) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* set a 32-bit const */ @@ -6702,7 +6849,7 @@ int mp_set_int (mp_int * a, unsigned long b) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* shrink a bignum */ @@ -6737,7 +6884,7 @@ int mp_shrink (mp_int * a) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* get the size for an signed equivalent */ @@ -6764,7 +6911,7 @@ int mp_signed_bin_size (mp_int * a) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* computes b = a*a */ @@ -6822,7 +6969,7 @@ if (a->used >= KARATSUBA_SQR_CUTOFF) { * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* c = a * a (mod b) */ @@ -6863,7 +7010,7 @@ mp_sqrmod (mp_int * a, mp_int * b, mp_int * c) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* this function is less generic than mp_n_root, simpler and faster */ @@ -6944,7 +7091,7 @@ E2: mp_clear(&t1); * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* high level subtraction (handles signs) */ @@ -7003,7 +7150,7 @@ mp_sub (mp_int * a, mp_int * b, mp_int * c) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* single digit subtraction */ @@ -7092,7 +7239,7 @@ mp_sub_d (mp_int * a, mp_digit b, mp_int * c) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* d = a - b (mod c) */ @@ -7134,12 +7281,11 @@ mp_submod (mp_int * a, mp_int * b, mp_int * c, mp_int * d) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* store in signed [big endian] format */ -int -mp_to_signed_bin (mp_int * a, unsigned char *b) +int mp_to_signed_bin (mp_int * a, unsigned char *b) { int res; @@ -7153,6 +7299,37 @@ mp_to_signed_bin (mp_int * a, unsigned char *b) /* End: bn_mp_to_signed_bin.c */ +/* Start: bn_mp_to_signed_bin_n.c */ +#include +#ifdef BN_MP_TO_SIGNED_BIN_N_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@gmail.com, http://math.libtomcrypt.org + */ + +/* store in signed [big endian] format */ +int mp_to_signed_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen) +{ + if (*outlen < (unsigned long)mp_signed_bin_size(a)) { + return MP_VAL; + } + *outlen = mp_signed_bin_size(a); + return mp_to_signed_bin(a, b); +} +#endif + +/* End: bn_mp_to_signed_bin_n.c */ + /* Start: bn_mp_to_unsigned_bin.c */ #include #ifdef BN_MP_TO_UNSIGNED_BIN_C @@ -7168,12 +7345,11 @@ mp_to_signed_bin (mp_int * a, unsigned char *b) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* store in unsigned [big endian] format */ -int -mp_to_unsigned_bin (mp_int * a, unsigned char *b) +int mp_to_unsigned_bin (mp_int * a, unsigned char *b) { int x, res; mp_int t; @@ -7202,6 +7378,37 @@ mp_to_unsigned_bin (mp_int * a, unsigned char *b) /* End: bn_mp_to_unsigned_bin.c */ +/* Start: bn_mp_to_unsigned_bin_n.c */ +#include +#ifdef BN_MP_TO_UNSIGNED_BIN_N_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@gmail.com, http://math.libtomcrypt.org + */ + +/* store in unsigned [big endian] format */ +int mp_to_unsigned_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen) +{ + if (*outlen < (unsigned long)mp_unsigned_bin_size(a)) { + return MP_VAL; + } + *outlen = mp_unsigned_bin_size(a); + return mp_to_unsigned_bin(a, b); +} +#endif + +/* End: bn_mp_to_unsigned_bin_n.c */ + /* Start: bn_mp_toom_mul.c */ #include #ifdef BN_MP_TOOM_MUL_C @@ -7217,14 +7424,15 @@ mp_to_unsigned_bin (mp_int * a, unsigned char *b) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* 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...). + * 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) { @@ -7500,7 +7708,7 @@ ERR: * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* squaring using Toom-Cook 3-way algorithm */ @@ -7726,7 +7934,7 @@ ERR: * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* stores a bignum as a ASCII string in a given radix (2..64) */ @@ -7801,7 +8009,7 @@ int mp_toradix (mp_int * a, char *str, int radix) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* stores a bignum as a ASCII string in a given radix (2..64) @@ -7890,12 +8098,11 @@ int mp_toradix_n(mp_int * a, char *str, int radix, int maxlen) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* get the size for an unsigned equivalent */ -int -mp_unsigned_bin_size (mp_int * a) +int mp_unsigned_bin_size (mp_int * a) { int size = mp_count_bits (a); return (size / 8 + ((size & 7) != 0 ? 1 : 0)); @@ -7919,7 +8126,7 @@ mp_unsigned_bin_size (mp_int * a) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* XOR two ints together */ @@ -7944,7 +8151,7 @@ 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); @@ -7970,16 +8177,22 @@ mp_xor (mp_int * a, mp_int * b, mp_int * c) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* set to zero */ -void -mp_zero (mp_int * a) +void mp_zero (mp_int * a) { + int n; + mp_digit *tmp; + a->sign = MP_ZPOS; a->used = 0; - memset (a->dp, 0, sizeof (mp_digit) * a->alloc); + + tmp = a->dp; + for (n = 0; n < a->alloc; n++) { + *tmp++ = 0; + } } #endif @@ -8000,7 +8213,7 @@ mp_zero (mp_int * a) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ const mp_digit ltm_prime_tab[] = { 0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013, @@ -8061,7 +8274,7 @@ const mp_digit ltm_prime_tab[] = { * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* reverse an array, used for radix code */ @@ -8100,7 +8313,7 @@ bn_reverse (unsigned char *s, int len) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* low level addition, based on HAC pp.594, Algorithm 14.7 */ @@ -8209,7 +8422,7 @@ s_mp_add (mp_int * a, mp_int * b, mp_int * c) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ #ifdef MP_LOW_MEM @@ -8218,11 +8431,12 @@ s_mp_add (mp_int * a, mp_int * b, mp_int * c) #define TAB_SIZE 256 #endif -int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) +int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) { mp_int M[TAB_SIZE], res, mu; mp_digit buf; int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize; + int (*redux)(mp_int*,mp_int*,mp_int*); /* find window size */ x = mp_count_bits (X); @@ -8269,9 +8483,18 @@ int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) if ((err = mp_init (&mu)) != MP_OKAY) { goto LBL_M; } - if ((err = mp_reduce_setup (&mu, P)) != MP_OKAY) { - goto LBL_MU; - } + + if (redmode == 0) { + if ((err = mp_reduce_setup (&mu, P)) != MP_OKAY) { + goto LBL_MU; + } + redux = mp_reduce; + } else { + if ((err = mp_reduce_2k_setup_l (P, &mu)) != MP_OKAY) { + goto LBL_MU; + } + redux = mp_reduce_2k_l; + } /* create M table * @@ -8293,11 +8516,14 @@ int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) } for (x = 0; x < (winsize - 1); x++) { + /* square it */ if ((err = mp_sqr (&M[1 << (winsize - 1)], &M[1 << (winsize - 1)])) != MP_OKAY) { goto LBL_MU; } - if ((err = mp_reduce (&M[1 << (winsize - 1)], P, &mu)) != MP_OKAY) { + + /* reduce modulo P */ + if ((err = redux (&M[1 << (winsize - 1)], P, &mu)) != MP_OKAY) { goto LBL_MU; } } @@ -8309,7 +8535,7 @@ int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) { goto LBL_MU; } - if ((err = mp_reduce (&M[x], P, &mu)) != MP_OKAY) { + if ((err = redux (&M[x], P, &mu)) != MP_OKAY) { goto LBL_MU; } } @@ -8358,7 +8584,7 @@ int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) if ((err = mp_sqr (&res, &res)) != MP_OKAY) { goto LBL_RES; } - if ((err = mp_reduce (&res, P, &mu)) != MP_OKAY) { + if ((err = redux (&res, P, &mu)) != MP_OKAY) { goto LBL_RES; } continue; @@ -8375,7 +8601,7 @@ int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) if ((err = mp_sqr (&res, &res)) != MP_OKAY) { goto LBL_RES; } - if ((err = mp_reduce (&res, P, &mu)) != MP_OKAY) { + if ((err = redux (&res, P, &mu)) != MP_OKAY) { goto LBL_RES; } } @@ -8384,7 +8610,7 @@ int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) { goto LBL_RES; } - if ((err = mp_reduce (&res, P, &mu)) != MP_OKAY) { + if ((err = redux (&res, P, &mu)) != MP_OKAY) { goto LBL_RES; } @@ -8402,7 +8628,7 @@ int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) if ((err = mp_sqr (&res, &res)) != MP_OKAY) { goto LBL_RES; } - if ((err = mp_reduce (&res, P, &mu)) != MP_OKAY) { + if ((err = redux (&res, P, &mu)) != MP_OKAY) { goto LBL_RES; } @@ -8412,7 +8638,7 @@ int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) { goto LBL_RES; } - if ((err = mp_reduce (&res, P, &mu)) != MP_OKAY) { + if ((err = redux (&res, P, &mu)) != MP_OKAY) { goto LBL_RES; } } @@ -8449,15 +8675,14 @@ LBL_M: * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* multiplies |a| * |b| and only computes upto digs digits of result * HAC pp. 595, Algorithm 14.12 Modified so you can control how * many digits of output are created. */ -int -s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) +int s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) { mp_int t; int res, pa, pb, ix, iy; @@ -8540,7 +8765,7 @@ s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* multiplies |a| * |b| and does not compute the lower digs digits @@ -8621,12 +8846,11 @@ s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* low level squaring, b = a*a, HAC pp.596-597, Algorithm 14.16 */ -int -s_mp_sqr (mp_int * a, mp_int * b) +int s_mp_sqr (mp_int * a, mp_int * b) { mp_int t; int res, ix, iy, pa; @@ -8706,7 +8930,7 @@ s_mp_sqr (mp_int * a, mp_int * b) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* low level subtraction (assumes |a| > |b|), HAC pp.595 Algorithm 14.9 */ @@ -8795,7 +9019,7 @@ s_mp_sub (mp_int * a, mp_int * b, mp_int * c) * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.org */ /* Known optimal configurations @@ -8803,11 +9027,12 @@ s_mp_sub (mp_int * a, mp_int * b, mp_int * c) CPU /Compiler /MUL CUTOFF/SQR CUTOFF ------------------------------------------------------------- Intel P4 Northwood /GCC v3.4.1 / 88/ 128/LTM 0.32 ;-) + AMD Athlon64 /GCC v3.4.4 / 74/ 124/LTM 0.34 */ -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. */ +int KARATSUBA_MUL_CUTOFF = 74, /* Min. number of digits before Karatsuba multiplication is used. */ + KARATSUBA_SQR_CUTOFF = 124, /* 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; diff --git a/src/misc/mpi/mpi_to_ltc_error.c b/src/misc/mpi/mpi_to_ltc_error.c index 0fa590d..3a4ea17 100644 --- a/src/misc/mpi/mpi_to_ltc_error.c +++ b/src/misc/mpi/mpi_to_ltc_error.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/misc/mpi/rand_prime.c b/src/misc/mpi/rand_prime.c index c7d875c..97ddf73 100644 --- a/src/misc/mpi/rand_prime.c +++ b/src/misc/mpi/rand_prime.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" @@ -54,6 +54,7 @@ int rand_prime(mp_int *N, long len, prng_state *prng, int wprng) } else { type = 0; } + type |= LTM_PRIME_2MSB_ON; /* New prime generation makes the code even more cryptoish-insane. Do you know what this means!!! -- Gir: Yeah, oh wait, er, no. diff --git a/src/misc/pkcs5/pkcs_5_1.c b/src/misc/pkcs5/pkcs_5_1.c index 7c0c805..ec47372 100644 --- a/src/misc/pkcs5/pkcs_5_1.c +++ b/src/misc/pkcs5/pkcs_5_1.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include @@ -74,7 +74,7 @@ int pkcs_5_alg1(const unsigned char *password, unsigned long password_len, } while (--iteration_count) { - // code goes here. + /* code goes here. */ x = MAXBLOCKSIZE; if ((err = hash_memory(hash_idx, buf, hash_descriptor[hash_idx].hashsize, buf, &x)) != CRYPT_OK) { goto LBL_ERR; diff --git a/src/misc/pkcs5/pkcs_5_2.c b/src/misc/pkcs5/pkcs_5_2.c index 57cbd80..aac811b 100644 --- a/src/misc/pkcs5/pkcs_5_2.c +++ b/src/misc/pkcs5/pkcs_5_2.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include @@ -34,7 +34,8 @@ int pkcs_5_alg2(const unsigned char *password, unsigned long password_len, unsigned char *out, unsigned long *outlen) { int err, itts; - unsigned long stored, left, x, y, blkno; + ulong32 blkno; + unsigned long stored, left, x, y; unsigned char *buf[2]; hmac_state *hmac; diff --git a/src/misc/zeromem.c b/src/misc/zeromem.c index 92f5f37..c640bb4 100644 --- a/src/misc/zeromem.c +++ b/src/misc/zeromem.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" @@ -22,8 +22,9 @@ */ void zeromem(void *out, size_t outlen) { - unsigned char *mem = (unsigned char *)out; - LTC_ARGCHK(out != NULL); - while (outlen-- > 0) - *mem++ = 0; + unsigned char *mem = out; + LTC_ARGCHK(out != NULL); + while (outlen-- > 0) { + *mem++ = 0; + } } diff --git a/src/modes/cbc/cbc_decrypt.c b/src/modes/cbc/cbc_decrypt.c index 0343268..c79631c 100644 --- a/src/modes/cbc/cbc_decrypt.c +++ b/src/modes/cbc/cbc_decrypt.c @@ -6,64 +6,86 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" /** @file cbc_decrypt.c - CBC implementation, decrypt block, Tom St Denis + CBC implementation, encrypt block, Tom St Denis */ + #ifdef CBC /** - CBC decrypt - @param ct Ciphertext - @param pt [out] Plaintext - @param cbc CBC state - @return CRYPT_OK if successful + CBC decrypt + @param ct Ciphertext + @param pt [out] Plaintext + @param len The number of bytes to process (must be multiple of block length) + @param cbc CBC state + @return CRYPT_OK if successful */ -int cbc_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_CBC *cbc) +int cbc_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CBC *cbc) { int x, err; - unsigned char tmp[MAXBLOCKSIZE], tmp2[MAXBLOCKSIZE]; + unsigned char tmp[16]; +#ifdef LTC_FAST + LTC_FAST_TYPE tmpy; +#else + unsigned char tmpy; +#endif - LTC_ARGCHK(pt != NULL); - LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); LTC_ARGCHK(cbc != NULL); - /* decrypt the block from ct into tmp */ if ((err = cipher_is_valid(cbc->cipher)) != CRYPT_OK) { return err; } - LTC_ARGCHK(cipher_descriptor[cbc->cipher].ecb_decrypt != NULL); - + /* is blocklen valid? */ if (cbc->blocklen < 0 || cbc->blocklen > (int)sizeof(cbc->IV)) { return CRYPT_INVALID_ARG; - } + } - /* decrypt and xor IV against the plaintext of the previous step */ - cipher_descriptor[cbc->cipher].ecb_decrypt(ct, tmp, &cbc->key); - for (x = 0; x < cbc->blocklen; x++) { - /* copy CT in case ct == pt */ - tmp2[x] = ct[x]; - - /* actually decrypt the byte */ - pt[x] = tmp[x] ^ cbc->IV[x]; + if (len % cbc->blocklen) { + return CRYPT_INVALID_ARG; } - - /* replace IV with this current ciphertext */ - for (x = 0; x < cbc->blocklen; x++) { - cbc->IV[x] = tmp2[x]; +#ifdef LTC_FAST + if (len % sizeof(LTC_FAST_TYPE)) { + return CRYPT_INVALID_ARG; + } +#endif + + if (cipher_descriptor[cbc->cipher].accel_cbc_decrypt != NULL) { + cipher_descriptor[cbc->cipher].accel_cbc_decrypt(ct, pt, len / cbc->blocklen, cbc->IV, &cbc->key); + } else { + while (len) { + /* decrypt */ + cipher_descriptor[cbc->cipher].ecb_decrypt(ct, tmp, &cbc->key); + + /* xor IV against plaintext */ + #if defined(LTC_FAST) + for (x = 0; x < cbc->blocklen; x += sizeof(LTC_FAST_TYPE)) { + tmpy = *((LTC_FAST_TYPE*)((unsigned char *)cbc->IV + x)) ^ *((LTC_FAST_TYPE*)((unsigned char *)tmp + x)); + *((LTC_FAST_TYPE*)((unsigned char *)cbc->IV + x)) = *((LTC_FAST_TYPE*)((unsigned char *)ct + x)); + *((LTC_FAST_TYPE*)((unsigned char *)pt + x)) = tmpy; + } + #else + for (x = 0; x < cbc->blocklen; x++) { + tmpy = tmp[x] ^ cbc->IV[x]; + cbc->IV[x] = ct[x]; + pt[x] = tmpy; + } + #endif + + ct += cbc->blocklen; + pt += cbc->blocklen; + len -= cbc->blocklen; + } } - #ifdef LTC_CLEAN_STACK - zeromem(tmp, sizeof(tmp)); - zeromem(tmp2, sizeof(tmp2)); - #endif return CRYPT_OK; } #endif - diff --git a/src/modes/cbc/cbc_done.c b/src/modes/cbc/cbc_done.c new file mode 100644 index 0000000..daa9110 --- /dev/null +++ b/src/modes/cbc/cbc_done.c @@ -0,0 +1,38 @@ +/* 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@gmail.com, http://libtomcrypt.org + */ +#include "tomcrypt.h" + +/** + @file cbc_done.c + CBC implementation, finish chain, Tom St Denis +*/ + +#ifdef CBC + +/** Terminate the chain + @param cbc The CBC chain to terminate + @return CRYPT_OK on success +*/ +int cbc_done(symmetric_CBC *cbc) +{ + int err; + LTC_ARGCHK(cbc != NULL); + + if ((err = cipher_is_valid(cbc->cipher)) != CRYPT_OK) { + return err; + } + cipher_descriptor[cbc->cipher].done(&cbc->key); + return CRYPT_OK; +} + + + +#endif diff --git a/src/modes/cbc/cbc_encrypt.c b/src/modes/cbc/cbc_encrypt.c index bd665de..00ca05f 100644 --- a/src/modes/cbc/cbc_encrypt.c +++ b/src/modes/cbc/cbc_encrypt.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" @@ -22,13 +22,13 @@ CBC encrypt @param pt Plaintext @param ct [out] Ciphertext + @param len The number of bytes to process (must be multiple of block length) @param cbc CBC state @return CRYPT_OK if successful */ -int cbc_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_CBC *cbc) +int cbc_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CBC *cbc) { int x, err; - unsigned char tmp[MAXBLOCKSIZE]; LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); @@ -43,22 +43,49 @@ int cbc_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_CBC *cbc) return CRYPT_INVALID_ARG; } - /* xor IV against plaintext */ - for (x = 0; x < cbc->blocklen; x++) { - tmp[x] = pt[x] ^ cbc->IV[x]; + if (len % cbc->blocklen) { + return CRYPT_INVALID_ARG; } - - /* encrypt */ - cipher_descriptor[cbc->cipher].ecb_encrypt(tmp, ct, &cbc->key); - - /* store IV [ciphertext] for a future block */ - for (x = 0; x < cbc->blocklen; x++) { - cbc->IV[x] = ct[x]; +#ifdef LTC_FAST + if (len % sizeof(LTC_FAST_TYPE)) { + return CRYPT_INVALID_ARG; } +#endif - #ifdef LTC_CLEAN_STACK - zeromem(tmp, sizeof(tmp)); - #endif + if (cipher_descriptor[cbc->cipher].accel_cbc_encrypt != NULL) { + cipher_descriptor[cbc->cipher].accel_cbc_encrypt(pt, ct, len / cbc->blocklen, cbc->IV, &cbc->key); + } else { + while (len) { + /* xor IV against plaintext */ + #if defined(LTC_FAST) + for (x = 0; x < cbc->blocklen; x += sizeof(LTC_FAST_TYPE)) { + *((LTC_FAST_TYPE*)((unsigned char *)cbc->IV + x)) ^= *((LTC_FAST_TYPE*)((unsigned char *)pt + x)); + } + #else + for (x = 0; x < cbc->blocklen; x++) { + cbc->IV[x] ^= pt[x]; + } + #endif + + /* encrypt */ + cipher_descriptor[cbc->cipher].ecb_encrypt(cbc->IV, ct, &cbc->key); + + /* store IV [ciphertext] for a future block */ + #if defined(LTC_FAST) + for (x = 0; x < cbc->blocklen; x += sizeof(LTC_FAST_TYPE)) { + *((LTC_FAST_TYPE*)((unsigned char *)cbc->IV + x)) = *((LTC_FAST_TYPE*)((unsigned char *)ct + x)); + } + #else + for (x = 0; x < cbc->blocklen; x++) { + cbc->IV[x] = ct[x]; + } + #endif + + ct += cbc->blocklen; + pt += cbc->blocklen; + len -= cbc->blocklen; + } + } return CRYPT_OK; } diff --git a/src/modes/cbc/cbc_getiv.c b/src/modes/cbc/cbc_getiv.c index 86e4eb6..0f5c3e4 100644 --- a/src/modes/cbc/cbc_getiv.c +++ b/src/modes/cbc/cbc_getiv.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/modes/cbc/cbc_setiv.c b/src/modes/cbc/cbc_setiv.c index 034a516..f2e8b31 100644 --- a/src/modes/cbc/cbc_setiv.c +++ b/src/modes/cbc/cbc_setiv.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/modes/cbc/cbc_start.c b/src/modes/cbc/cbc_start.c index df2e6a1..680faab 100644 --- a/src/modes/cbc/cbc_start.c +++ b/src/modes/cbc/cbc_start.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/modes/cfb/cfb_decrypt.c b/src/modes/cfb/cfb_decrypt.c index 27930b0..8b78898 100644 --- a/src/modes/cfb/cfb_decrypt.c +++ b/src/modes/cfb/cfb_decrypt.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/modes/cfb/cfb_done.c b/src/modes/cfb/cfb_done.c new file mode 100644 index 0000000..04e775c --- /dev/null +++ b/src/modes/cfb/cfb_done.c @@ -0,0 +1,38 @@ +/* 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@gmail.com, http://libtomcrypt.org + */ +#include "tomcrypt.h" + +/** + @file cfb_done.c + CFB implementation, finish chain, Tom St Denis +*/ + +#ifdef CFB + +/** Terminate the chain + @param cfb The CFB chain to terminate + @return CRYPT_OK on success +*/ +int cfb_done(symmetric_CFB *cfb) +{ + int err; + LTC_ARGCHK(cfb != NULL); + + if ((err = cipher_is_valid(cfb->cipher)) != CRYPT_OK) { + return err; + } + cipher_descriptor[cfb->cipher].done(&cfb->key); + return CRYPT_OK; +} + + + +#endif diff --git a/src/modes/cfb/cfb_encrypt.c b/src/modes/cfb/cfb_encrypt.c index f6d39ae..b960368 100644 --- a/src/modes/cfb/cfb_encrypt.c +++ b/src/modes/cfb/cfb_encrypt.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/modes/cfb/cfb_getiv.c b/src/modes/cfb/cfb_getiv.c index 27720a8..e59c1e4 100644 --- a/src/modes/cfb/cfb_getiv.c +++ b/src/modes/cfb/cfb_getiv.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/modes/cfb/cfb_setiv.c b/src/modes/cfb/cfb_setiv.c index 6745b2c..e475ad9 100644 --- a/src/modes/cfb/cfb_setiv.c +++ b/src/modes/cfb/cfb_setiv.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/modes/cfb/cfb_start.c b/src/modes/cfb/cfb_start.c index 209e175..7157fc3 100644 --- a/src/modes/cfb/cfb_start.c +++ b/src/modes/cfb/cfb_start.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/modes/ctr/ctr_decrypt.c b/src/modes/ctr/ctr_decrypt.c index 0277a43..daa78a8 100644 --- a/src/modes/ctr/ctr_decrypt.c +++ b/src/modes/ctr/ctr_decrypt.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/modes/ctr/ctr_done.c b/src/modes/ctr/ctr_done.c new file mode 100644 index 0000000..88508ba --- /dev/null +++ b/src/modes/ctr/ctr_done.c @@ -0,0 +1,38 @@ +/* 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@gmail.com, http://libtomcrypt.org + */ +#include "tomcrypt.h" + +/** + @file ctr_done.c + CTR implementation, finish chain, Tom St Denis +*/ + +#ifdef CTR + +/** Terminate the chain + @param ctr The CTR chain to terminate + @return CRYPT_OK on success +*/ +int ctr_done(symmetric_CTR *ctr) +{ + int err; + LTC_ARGCHK(ctr != NULL); + + if ((err = cipher_is_valid(ctr->cipher)) != CRYPT_OK) { + return err; + } + cipher_descriptor[ctr->cipher].done(&ctr->key); + return CRYPT_OK; +} + + + +#endif diff --git a/src/modes/ctr/ctr_encrypt.c b/src/modes/ctr/ctr_encrypt.c index ca22554..a96b806 100644 --- a/src/modes/ctr/ctr_encrypt.c +++ b/src/modes/ctr/ctr_encrypt.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" @@ -44,7 +44,19 @@ int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s return CRYPT_INVALID_ARG; } - while (len-- > 0) { +#ifdef LTC_FAST + if (ctr->blocklen % sizeof(LTC_FAST_TYPE)) { + return CRYPT_INVALID_ARG; + } +#endif + + /* handle acceleration only if pad is empty, accelerator is present and length is >= a block size */ + if ((ctr->padlen == ctr->blocklen) && cipher_descriptor[ctr->cipher].accel_ctr_encrypt != NULL && (len >= (unsigned long)ctr->blocklen)) { + cipher_descriptor[ctr->cipher].accel_ctr_encrypt(pt, ct, len/ctr->blocklen, ctr->ctr, ctr->mode, &ctr->key); + len %= ctr->blocklen; + } + + while (len) { /* is the pad empty? */ if (ctr->padlen == ctr->blocklen) { /* increment counter */ @@ -70,7 +82,21 @@ int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key); ctr->padlen = 0; } - *ct++ = *pt++ ^ ctr->pad[ctr->padlen++]; +#ifdef LTC_FAST + if (ctr->padlen == 0 && len >= (unsigned long)ctr->blocklen) { + for (x = 0; x < ctr->blocklen; x += sizeof(LTC_FAST_TYPE)) { + *((LTC_FAST_TYPE*)((unsigned char *)ct + x)) = *((LTC_FAST_TYPE*)((unsigned char *)pt + x)) ^ + *((LTC_FAST_TYPE*)((unsigned char *)ctr->pad + x)); + } + pt += ctr->blocklen; + ct += ctr->blocklen; + len -= ctr->blocklen; + ctr->padlen = ctr->blocklen; + continue; + } +#endif + *ct++ = *pt++ ^ ctr->pad[ctr->padlen++]; + --len; } return CRYPT_OK; } diff --git a/src/modes/ctr/ctr_getiv.c b/src/modes/ctr/ctr_getiv.c index c05ba21..3997033 100644 --- a/src/modes/ctr/ctr_getiv.c +++ b/src/modes/ctr/ctr_getiv.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/modes/ctr/ctr_setiv.c b/src/modes/ctr/ctr_setiv.c index c97d1d1..2aab190 100644 --- a/src/modes/ctr/ctr_setiv.c +++ b/src/modes/ctr/ctr_setiv.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/modes/ctr/ctr_start.c b/src/modes/ctr/ctr_start.c index fc0a104..db8c464 100644 --- a/src/modes/ctr/ctr_start.c +++ b/src/modes/ctr/ctr_start.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/modes/ecb/ecb_decrypt.c b/src/modes/ecb/ecb_decrypt.c index d60bad2..8db4d37 100644 --- a/src/modes/ecb/ecb_decrypt.c +++ b/src/modes/ecb/ecb_decrypt.c @@ -6,41 +6,50 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" /** @file ecb_decrypt.c - ECB implementation, decrypt block, Tom St Denis + ECB implementation, decrypt a block, Tom St Denis */ #ifdef ECB /** - ECB decrypt - @param ct Ciphertext - @param pt [out] Plaintext - @param ecb ECB state - @return CRYPT_OK if successful + ECB decrypt + @param ct Ciphertext + @param pt [out] Plaintext + @param len The number of octets to process (must be multiple of the cipher block size) + @param ecb ECB state + @return CRYPT_OK if successful */ -int ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_ECB *ecb) +int ecb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_ECB *ecb) { int err; LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(ecb != NULL); - - /* valid cipher? */ if ((err = cipher_is_valid(ecb->cipher)) != CRYPT_OK) { return err; } - LTC_ARGCHK(cipher_descriptor[ecb->cipher].ecb_decrypt != NULL); - - cipher_descriptor[ecb->cipher].ecb_decrypt(ct, pt, &ecb->key); + if (len % cipher_descriptor[ecb->cipher].block_length) { + return CRYPT_INVALID_ARG; + } + + /* check for accel */ + if (cipher_descriptor[ecb->cipher].accel_ecb_decrypt != NULL) { + cipher_descriptor[ecb->cipher].accel_ecb_decrypt(ct, pt, len / cipher_descriptor[ecb->cipher].block_length, &ecb->key); + } else { + while (len) { + cipher_descriptor[ecb->cipher].ecb_decrypt(ct, pt, &ecb->key); + pt += cipher_descriptor[ecb->cipher].block_length; + ct += cipher_descriptor[ecb->cipher].block_length; + len -= cipher_descriptor[ecb->cipher].block_length; + } + } return CRYPT_OK; } #endif - - diff --git a/src/modes/ecb/ecb_done.c b/src/modes/ecb/ecb_done.c new file mode 100644 index 0000000..31a42fa --- /dev/null +++ b/src/modes/ecb/ecb_done.c @@ -0,0 +1,38 @@ +/* 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@gmail.com, http://libtomcrypt.org + */ +#include "tomcrypt.h" + +/** + @file ecb_done.c + ECB implementation, finish chain, Tom St Denis +*/ + +#ifdef ECB + +/** Terminate the chain + @param rcb The ECB chain to terminate + @return CRYPT_OK on success +*/ +int ecb_done(symmetric_ECB *ecb) +{ + int err; + LTC_ARGCHK(ecb != NULL); + + if ((err = cipher_is_valid(ecb->cipher)) != CRYPT_OK) { + return err; + } + cipher_descriptor[ecb->cipher].done(&ecb->key); + return CRYPT_OK; +} + + + +#endif diff --git a/src/modes/ecb/ecb_encrypt.c b/src/modes/ecb/ecb_encrypt.c index 68b6e5d..dc045e9 100644 --- a/src/modes/ecb/ecb_encrypt.c +++ b/src/modes/ecb/ecb_encrypt.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" @@ -21,20 +21,34 @@ ECB encrypt @param pt Plaintext @param ct [out] Ciphertext + @param len The number of octets to process (must be multiple of the cipher block size) @param ecb ECB state @return CRYPT_OK if successful */ -int ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_ECB *ecb) +int ecb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_ECB *ecb) { int err; LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(ecb != NULL); - if ((err = cipher_is_valid(ecb->cipher)) != CRYPT_OK) { return err; } - cipher_descriptor[ecb->cipher].ecb_encrypt(pt, ct, &ecb->key); + if (len % cipher_descriptor[ecb->cipher].block_length) { + return CRYPT_INVALID_ARG; + } + + /* check for accel */ + if (cipher_descriptor[ecb->cipher].accel_ecb_encrypt != NULL) { + cipher_descriptor[ecb->cipher].accel_ecb_encrypt(pt, ct, len / cipher_descriptor[ecb->cipher].block_length, &ecb->key); + } else { + while (len) { + cipher_descriptor[ecb->cipher].ecb_encrypt(pt, ct, &ecb->key); + pt += cipher_descriptor[ecb->cipher].block_length; + ct += cipher_descriptor[ecb->cipher].block_length; + len -= cipher_descriptor[ecb->cipher].block_length; + } + } return CRYPT_OK; } diff --git a/src/modes/ecb/ecb_start.c b/src/modes/ecb/ecb_start.c index c84b3c7..a8b6d45 100644 --- a/src/modes/ecb/ecb_start.c +++ b/src/modes/ecb/ecb_start.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/modes/ofb/ofb_decrypt.c b/src/modes/ofb/ofb_decrypt.c index 732daf7..f725410 100644 --- a/src/modes/ofb/ofb_decrypt.c +++ b/src/modes/ofb/ofb_decrypt.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/modes/ofb/ofb_done.c b/src/modes/ofb/ofb_done.c new file mode 100644 index 0000000..ff72ddc --- /dev/null +++ b/src/modes/ofb/ofb_done.c @@ -0,0 +1,38 @@ +/* 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@gmail.com, http://libtomcrypt.org + */ +#include "tomcrypt.h" + +/** + @file ofb_done.c + OFB implementation, finish chain, Tom St Denis +*/ + +#ifdef OFB + +/** Terminate the chain + @param ofb The OFB chain to terminate + @return CRYPT_OK on success +*/ +int ofb_done(symmetric_OFB *ofb) +{ + int err; + LTC_ARGCHK(ofb != NULL); + + if ((err = cipher_is_valid(ofb->cipher)) != CRYPT_OK) { + return err; + } + cipher_descriptor[ofb->cipher].done(&ofb->key); + return CRYPT_OK; +} + + + +#endif diff --git a/src/modes/ofb/ofb_encrypt.c b/src/modes/ofb/ofb_encrypt.c index 56a3647..4409ac8 100644 --- a/src/modes/ofb/ofb_encrypt.c +++ b/src/modes/ofb/ofb_encrypt.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/modes/ofb/ofb_getiv.c b/src/modes/ofb/ofb_getiv.c index 7211d95..eb8ef1e 100644 --- a/src/modes/ofb/ofb_getiv.c +++ b/src/modes/ofb/ofb_getiv.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/modes/ofb/ofb_setiv.c b/src/modes/ofb/ofb_setiv.c index af7b843..96b3f1c 100644 --- a/src/modes/ofb/ofb_setiv.c +++ b/src/modes/ofb/ofb_setiv.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/modes/ofb/ofb_start.c b/src/modes/ofb/ofb_start.c index 67dc2c6..977e6a3 100644 --- a/src/modes/ofb/ofb_start.c +++ b/src/modes/ofb/ofb_start.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/pk/asn1/der/der_decode_integer.c b/src/pk/asn1/der/der_decode_integer.c index 08ec619..b798bd4 100644 --- a/src/pk/asn1/der/der_decode_integer.c +++ b/src/pk/asn1/der/der_decode_integer.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/pk/asn1/der/der_encode_integer.c b/src/pk/asn1/der/der_encode_integer.c index 460eace..c5c5267 100644 --- a/src/pk/asn1/der/der_encode_integer.c +++ b/src/pk/asn1/der/der_encode_integer.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/pk/asn1/der/der_get_multi_integer.c b/src/pk/asn1/der/der_get_multi_integer.c index e4d5c1b..75ae0bc 100644 --- a/src/pk/asn1/der/der_get_multi_integer.c +++ b/src/pk/asn1/der/der_get_multi_integer.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include #include "tomcrypt.h" diff --git a/src/pk/asn1/der/der_length_integer.c b/src/pk/asn1/der/der_length_integer.c index ff9a394..f86738a 100644 --- a/src/pk/asn1/der/der_length_integer.c +++ b/src/pk/asn1/der/der_length_integer.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/pk/asn1/der/der_put_multi_integer.c b/src/pk/asn1/der/der_put_multi_integer.c index 44f5ef3..af2ca88 100644 --- a/src/pk/asn1/der/der_put_multi_integer.c +++ b/src/pk/asn1/der/der_put_multi_integer.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include #include "tomcrypt.h" diff --git a/src/pk/dh/dh.c b/src/pk/dh/dh.c index a70e594..c2085a6 100644 --- a/src/pk/dh/dh.c +++ b/src/pk/dh/dh.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/pk/dh/dh_sys.c b/src/pk/dh/dh_sys.c index 0596b37..801f85a 100644 --- a/src/pk/dh/dh_sys.c +++ b/src/pk/dh/dh_sys.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ /** diff --git a/src/pk/dsa/dsa_export.c b/src/pk/dsa/dsa_export.c index 35c16fe..773023e 100644 --- a/src/pk/dsa/dsa_export.c +++ b/src/pk/dsa/dsa_export.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/pk/dsa/dsa_free.c b/src/pk/dsa/dsa_free.c index d8d3ddf..862a2dd 100644 --- a/src/pk/dsa/dsa_free.c +++ b/src/pk/dsa/dsa_free.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/pk/dsa/dsa_import.c b/src/pk/dsa/dsa_import.c index 73c2a55..6de56e3 100644 --- a/src/pk/dsa/dsa_import.c +++ b/src/pk/dsa/dsa_import.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/pk/dsa/dsa_make_key.c b/src/pk/dsa/dsa_make_key.c index d5dd889..60683a0 100644 --- a/src/pk/dsa/dsa_make_key.c +++ b/src/pk/dsa/dsa_make_key.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/pk/dsa/dsa_sign_hash.c b/src/pk/dsa/dsa_sign_hash.c index 38ae121..da92a82 100644 --- a/src/pk/dsa/dsa_sign_hash.c +++ b/src/pk/dsa/dsa_sign_hash.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/pk/dsa/dsa_verify_hash.c b/src/pk/dsa/dsa_verify_hash.c index 391cc24..140f0e2 100644 --- a/src/pk/dsa/dsa_verify_hash.c +++ b/src/pk/dsa/dsa_verify_hash.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/pk/dsa/dsa_verify_key.c b/src/pk/dsa/dsa_verify_key.c index 3039668..3e84261 100644 --- a/src/pk/dsa/dsa_verify_key.c +++ b/src/pk/dsa/dsa_verify_key.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/pk/ecc/ecc.c b/src/pk/ecc/ecc.c index cb99dde..b5e088b 100644 --- a/src/pk/ecc/ecc.c +++ b/src/pk/ecc/ecc.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b @@ -247,7 +247,7 @@ static ecc_point *new_point(void) if (p == NULL) { return NULL; } - if (mp_init_multi(&p->x, &p->y, NULL) != MP_OKAY) { + if (mp_init_multi(&p->x, &p->y, &p->z, NULL) != MP_OKAY) { XFREE(p); return NULL; } @@ -258,113 +258,294 @@ static void del_point(ecc_point *p) { /* prevents free'ing null arguments */ if (p != NULL) { - mp_clear_multi(&p->x, &p->y, NULL); + mp_clear_multi(&p->x, &p->y, &p->z, NULL); XFREE(p); } } -/* double a point R = 2P, R can be P*/ -static int dbl_point(ecc_point *P, ecc_point *R, mp_int *modulus, mp_int *mu) +static int ecc_map(ecc_point *P, mp_int *modulus, mp_int *mu) { - mp_int s, tmp, tmpx; + mp_int t1, t2; int err; - if ((err = mp_init_multi(&s, &tmp, &tmpx, NULL)) != MP_OKAY) { - return mpi_to_ltc_error(err); + if ((err = mp_init_multi(&t1, &t2, NULL)) != CRYPT_OK) { + return CRYPT_MEM; } - /* s = (3Xp^2 + a) / (2Yp) */ - if ((err = mp_mul_2(&P->y, &tmp)) != MP_OKAY) { goto error; } /* tmp = 2*y */ - if ((err = mp_invmod(&tmp, modulus, &tmp)) != MP_OKAY) { goto error; } /* tmp = 1/tmp mod modulus */ - if ((err = mp_sqr(&P->x, &s)) != MP_OKAY) { goto error; } /* s = x^2 */ - if ((err = mp_reduce(&s, modulus, mu)) != MP_OKAY) { goto error; } - if ((err = mp_mul_d(&s,(mp_digit)3, &s)) != MP_OKAY) { goto error; } /* s = 3*(x^2) */ - if ((err = mp_sub_d(&s,(mp_digit)3, &s)) != MP_OKAY) { goto error; } /* s = 3*(x^2) - 3 */ - if (mp_cmp_d(&s, 0) == MP_LT) { /* if s < 0 add modulus */ - if ((err = mp_add(&s, modulus, &s)) != MP_OKAY) { goto error; } - } - if ((err = mp_mul(&s, &tmp, &s)) != MP_OKAY) { goto error; } /* s = tmp * s mod modulus */ - if ((err = mp_reduce(&s, modulus, mu)) != MP_OKAY) { goto error; } + /* get 1/z */ + if ((err = mp_invmod(&P->z, modulus, &t1)) != MP_OKAY) { goto error; } + + /* get 1/z^2 and 1/z^3 */ + if ((err = mp_sqr(&t1, &t2)) != MP_OKAY) { goto error; } + if ((err = mp_reduce(&t2, modulus, mu)) != MP_OKAY) { goto error; } + if ((err = mp_mul(&t1, &t2, &t1)) != MP_OKAY) { goto error; } + if ((err = mp_reduce(&t1, modulus, mu)) != MP_OKAY) { goto error; } - /* Xr = s^2 - 2Xp */ - if ((err = mp_sqr(&s, &tmpx)) != MP_OKAY) { goto error; } /* tmpx = s^2 */ - if ((err = mp_reduce(&tmpx, modulus, mu)) != MP_OKAY) { goto error; } /* tmpx = tmpx mod modulus */ - if ((err = mp_sub(&tmpx, &P->x, &tmpx)) != MP_OKAY) { goto error; } /* tmpx = tmpx - x */ - if ((err = mp_submod(&tmpx, &P->x, modulus, &tmpx)) != MP_OKAY) { goto error; } /* tmpx = tmpx - x mod modulus */ - - /* Yr = -Yp + s(Xp - Xr) */ - if ((err = mp_sub(&P->x, &tmpx, &tmp)) != MP_OKAY) { goto error; } /* tmp = x - tmpx */ - if ((err = mp_mul(&tmp, &s, &tmp)) != MP_OKAY) { goto error; } /* tmp = tmp * s */ - if ((err = mp_submod(&tmp, &P->y, modulus, &R->y)) != MP_OKAY) { goto error; } /* y = tmp - y mod modulus */ - if ((err = mp_copy(&tmpx, &R->x)) != MP_OKAY) { goto error; } /* x = tmpx */ + /* multiply against x/y */ + if ((err = mp_mul(&P->x, &t2, &P->x)) != MP_OKAY) { goto error; } + if ((err = mp_reduce(&P->x, modulus, mu)) != MP_OKAY) { goto error; } + if ((err = mp_mul(&P->y, &t1, &P->y)) != MP_OKAY) { goto error; } + if ((err = mp_reduce(&P->y, modulus, mu)) != MP_OKAY) { goto error; } + mp_set(&P->z, 1); err = CRYPT_OK; goto done; error: err = mpi_to_ltc_error(err); done: - mp_clear_multi(&tmpx, &tmp, &s, NULL); + mp_clear_multi(&t1, &t2, NULL); + return err; + +} + + +/* double a point R = 2P, R can be P*/ +static int dbl_point(ecc_point *P, ecc_point *R, mp_int *modulus, mp_int *mu) +{ + mp_int t1, t2; + int err; + + if ((err = mp_init_multi(&t1, &t2, NULL)) != MP_OKAY) { + return mpi_to_ltc_error(err); + } + + if ((err = mp_copy(&P->x, &R->x)) != MP_OKAY) { goto error; } + if ((err = mp_copy(&P->y, &R->y)) != MP_OKAY) { goto error; } + if ((err = mp_copy(&P->z, &R->z)) != MP_OKAY) { goto error; } + + /* t1 = Z * Z */ + if ((err = mp_sqr(&R->z, &t1)) != MP_OKAY) { goto error; } + if ((err = mp_reduce(&t1, modulus, mu)) != MP_OKAY) { goto error; } + /* Z = Y * Z */ + if ((err = mp_mul(&R->z, &R->y, &R->z)) != MP_OKAY) { goto error; } + if ((err = mp_reduce(&R->z, modulus, mu)) != MP_OKAY) { goto error; } + /* Z = 2Z */ + if ((err = mp_mul_2(&R->z, &R->z)) != MP_OKAY) { goto error; } + if (mp_cmp(&R->z, modulus) != MP_LT) { + if ((err = mp_sub(&R->z, modulus, &R->z)) != MP_OKAY) { goto error; } + } + + /* T2 = X - T1 */ + if ((err = mp_sub(&R->x, &t1, &t2)) != MP_OKAY) { goto error; } + if (mp_cmp_d(&t2, 0) == MP_LT) { + if ((err = mp_add(&t2, modulus, &t2)) != MP_OKAY) { goto error; } + } + /* T1 = X + T1 */ + if ((err = mp_add(&t1, &R->x, &t1)) != MP_OKAY) { goto error; } + if (mp_cmp(&t1, modulus) != MP_LT) { + if ((err = mp_sub(&t1, modulus, &t1)) != MP_OKAY) { goto error; } + } + /* T2 = T1 * T2 */ + if ((err = mp_mul(&t1, &t2, &t2)) != MP_OKAY) { goto error; } + if ((err = mp_reduce(&t2, modulus, mu)) != MP_OKAY) { goto error; } + /* T1 = 2T2 */ + if ((err = mp_mul_2(&t2, &t1)) != MP_OKAY) { goto error; } + if (mp_cmp(&t1, modulus) != MP_LT) { + if ((err = mp_sub(&t1, modulus, &t1)) != MP_OKAY) { goto error; } + } + /* T1 = T1 + T2 */ + if ((err = mp_add(&t1, &t2, &t1)) != MP_OKAY) { goto error; } + if (mp_cmp(&t1, modulus) != MP_LT) { + if ((err = mp_sub(&t1, modulus, &t1)) != MP_OKAY) { goto error; } + } + + /* Y = 2Y */ + if ((err = mp_mul_2(&R->y, &R->y)) != MP_OKAY) { goto error; } + if (mp_cmp(&R->y, modulus) != MP_LT) { + if ((err = mp_sub(&R->y, modulus, &R->y)) != MP_OKAY) { goto error; } + } + /* Y = Y * Y */ + if ((err = mp_sqr(&R->y, &R->y)) != MP_OKAY) { goto error; } + if ((err = mp_reduce(&R->y, modulus, mu)) != MP_OKAY) { goto error; } + /* T2 = Y * Y */ + if ((err = mp_sqr(&R->y, &t2)) != MP_OKAY) { goto error; } + if ((err = mp_reduce(&t2, modulus, mu)) != MP_OKAY) { goto error; } + /* T2 = T2/2 */ + if (mp_isodd(&t2)) { + if ((err = mp_add(&t2, modulus, &t2)) != MP_OKAY) { goto error; } + } + if ((err = mp_div_2(&t2, &t2)) != MP_OKAY) { goto error; } + /* Y = Y * X */ + if ((err = mp_mul(&R->y, &R->x, &R->y)) != MP_OKAY) { goto error; } + if ((err = mp_reduce(&R->y, modulus, mu)) != MP_OKAY) { goto error; } + + /* X = T1 * T1 */ + if ((err = mp_sqr(&t1, &R->x)) != MP_OKAY) { goto error; } + if ((err = mp_reduce(&R->x, modulus, mu)) != MP_OKAY) { goto error; } + /* X = X - Y */ + if ((err = mp_sub(&R->x, &R->y, &R->x)) != MP_OKAY) { goto error; } + if (mp_cmp_d(&R->x, 0) == MP_LT) { + if ((err = mp_add(&R->x, modulus, &R->x)) != MP_OKAY) { goto error; } + } + /* X = X - Y */ + if ((err = mp_sub(&R->x, &R->y, &R->x)) != MP_OKAY) { goto error; } + if (mp_cmp_d(&R->x, 0) == MP_LT) { + if ((err = mp_add(&R->x, modulus, &R->x)) != MP_OKAY) { goto error; } + } + + /* Y = Y - X */ + if ((err = mp_sub(&R->y, &R->x, &R->y)) != MP_OKAY) { goto error; } + if (mp_cmp_d(&R->y, 0) == MP_LT) { + if ((err = mp_add(&R->y, modulus, &R->y)) != MP_OKAY) { goto error; } + } + /* Y = Y * T1 */ + if ((err = mp_mul(&R->y, &t1, &R->y)) != MP_OKAY) { goto error; } + if ((err = mp_reduce(&R->y, modulus, mu)) != MP_OKAY) { goto error; } + /* Y = Y - T2 */ + if ((err = mp_sub(&R->y, &t2, &R->y)) != MP_OKAY) { goto error; } + if (mp_cmp_d(&R->y, 0) == MP_LT) { + if ((err = mp_add(&R->y, modulus, &R->y)) != MP_OKAY) { goto error; } + } + + err = CRYPT_OK; + goto done; +error: + err = mpi_to_ltc_error(err); +done: + mp_clear_multi(&t1, &t2, NULL); return err; } /* add two different points over Z/pZ, R = P + Q, note R can equal either P or Q */ static int add_point(ecc_point *P, ecc_point *Q, ecc_point *R, mp_int *modulus, mp_int *mu) { - mp_int s, tmp, tmpx; + mp_int t1, t2, x, y, z; int err; - if ((err = mp_init(&tmp)) != MP_OKAY) { + if ((err = mp_init_multi(&t1, &t2, &x, &y, &z, NULL)) != MP_OKAY) { return mpi_to_ltc_error(err); } - /* is P==Q or P==-Q? */ - if (((err = mp_neg(&Q->y, &tmp)) != MP_OKAY) || ((err = mp_mod(&tmp, modulus, &tmp)) != MP_OKAY)) { - mp_clear(&tmp); - return mpi_to_ltc_error(err); + if ((err = mp_copy(&P->x, &x)) != MP_OKAY) { goto error; } + if ((err = mp_copy(&P->y, &y)) != MP_OKAY) { goto error; } + if ((err = mp_copy(&P->z, &z)) != MP_OKAY) { goto error; } + + /* if Z' != 1 */ + if (mp_cmp_d(&Q->z, 1) != MP_EQ) { + /* T1 = Z' * Z' */ + if ((err = mp_sqr(&Q->z, &t1)) != MP_OKAY) { goto error; } + if ((err = mp_reduce(&t1, modulus, mu)) != MP_OKAY) { goto error; } + /* X = X * T1 */ + if ((err = mp_mul(&t1, &x, &x)) != MP_OKAY) { goto error; } + if ((err = mp_reduce(&x, modulus, mu)) != MP_OKAY) { goto error; } + /* T1 = Z' * T1 */ + if ((err = mp_mul(&Q->z, &t1, &t1)) != MP_OKAY) { goto error; } + if ((err = mp_reduce(&t1, modulus, mu)) != MP_OKAY) { goto error; } + /* Y = Y * T1 */ + if ((err = mp_mul(&t1, &y, &y)) != MP_OKAY) { goto error; } + if ((err = mp_reduce(&y, modulus, mu)) != MP_OKAY) { goto error; } } - if (mp_cmp(&P->x, &Q->x) == MP_EQ) - if (mp_cmp(&P->y, &Q->y) == MP_EQ || mp_cmp(&P->y, &tmp) == MP_EQ) { - mp_clear(&tmp); - return dbl_point(P, R, modulus, mu); - } + /* T1 = Z*Z */ + if ((err = mp_sqr(&z, &t1)) != MP_OKAY) { goto error; } + if ((err = mp_reduce(&t1, modulus, mu)) != MP_OKAY) { goto error; } + /* T2 = X' * T1 */ + if ((err = mp_mul(&Q->x, &t1, &t2)) != MP_OKAY) { goto error; } + if ((err = mp_reduce(&t2, modulus, mu)) != MP_OKAY) { goto error; } + /* T1 = Z * T1 */ + if ((err = mp_mul(&z, &t1, &t1)) != MP_OKAY) { goto error; } + if ((err = mp_reduce(&t1, modulus, mu)) != MP_OKAY) { goto error; } + /* T1 = Y' * T1 */ + if ((err = mp_mul(&Q->y, &t1, &t1)) != MP_OKAY) { goto error; } + if ((err = mp_reduce(&t1, modulus, mu)) != MP_OKAY) { goto error; } - if ((err = mp_init_multi(&tmpx, &s, NULL)) != MP_OKAY) { - mp_clear(&tmp); - return mpi_to_ltc_error(err); + /* Y = Y - T1 */ + if ((err = mp_sub(&y, &t1, &y)) != MP_OKAY) { goto error; } + if (mp_cmp_d(&y, 0) == MP_LT) { + if ((err = mp_add(&y, modulus, &y)) != MP_OKAY) { goto error; } + } + /* T1 = 2T1 */ + if ((err = mp_mul_2(&t1, &t1)) != MP_OKAY) { goto error; } + if (mp_cmp(&t1, modulus) != MP_LT) { + if ((err = mp_sub(&t1, modulus, &t1)) != MP_OKAY) { goto error; } + } + /* T1 = Y + T1 */ + if ((err = mp_add(&t1, &y, &t1)) != MP_OKAY) { goto error; } + if (mp_cmp(&t1, modulus) != MP_LT) { + if ((err = mp_sub(&t1, modulus, &t1)) != MP_OKAY) { goto error; } + } + /* X = X - T2 */ + if ((err = mp_sub(&x, &t2, &x)) != MP_OKAY) { goto error; } + if (mp_cmp_d(&x, 0) == MP_LT) { + if ((err = mp_add(&x, modulus, &x)) != MP_OKAY) { goto error; } + } + /* T2 = 2T2 */ + if ((err = mp_mul_2(&t2, &t2)) != MP_OKAY) { goto error; } + if (mp_cmp(&t2, modulus) != MP_LT) { + if ((err = mp_sub(&t2, modulus, &t2)) != MP_OKAY) { goto error; } + } + /* T2 = X + T2 */ + if ((err = mp_add(&t2, &x, &t2)) != MP_OKAY) { goto error; } + if (mp_cmp(&t2, modulus) != MP_LT) { + if ((err = mp_sub(&t2, modulus, &t2)) != MP_OKAY) { goto error; } } - /* get s = (Yp - Yq)/(Xp-Xq) mod p */ - if ((err = mp_sub(&P->x, &Q->x, &tmp)) != MP_OKAY) { goto error; } /* tmp = Px - Qx mod modulus */ - if (mp_cmp_d(&tmp, 0) == MP_LT) { /* if tmp<0 add modulus */ - if ((err = mp_add(&tmp, modulus, &tmp)) != MP_OKAY) { goto error; } + /* if Z' != 1 */ + if (mp_cmp_d(&Q->z, 1) != MP_EQ) { + /* Z = Z * Z' */ + if ((err = mp_mul(&z, &Q->z, &z)) != MP_OKAY) { goto error; } + if ((err = mp_reduce(&z, modulus, mu)) != MP_OKAY) { goto error; } } - if ((err = mp_invmod(&tmp, modulus, &tmp)) != MP_OKAY) { goto error; } /* tmp = 1/tmp mod modulus */ - if ((err = mp_sub(&P->y, &Q->y, &s)) != MP_OKAY) { goto error; } /* s = Py - Qy mod modulus */ - if (mp_cmp_d(&s, 0) == MP_LT) { /* if s<0 add modulus */ - if ((err = mp_add(&s, modulus, &s)) != MP_OKAY) { goto error; } + /* Z = Z * X */ + if ((err = mp_mul(&z, &x, &z)) != MP_OKAY) { goto error; } + if ((err = mp_reduce(&z, modulus, mu)) != MP_OKAY) { goto error; } + + /* T1 = T1 * X */ + if ((err = mp_mul(&t1, &x, &t1)) != MP_OKAY) { goto error; } + if ((err = mp_reduce(&t1, modulus, mu)) != MP_OKAY) { goto error; } + /* X = X * X */ + if ((err = mp_sqr(&x, &x)) != MP_OKAY) { goto error; } + if ((err = mp_reduce(&x, modulus, mu)) != MP_OKAY) { goto error; } + /* T2 = T2 * x */ + if ((err = mp_mul(&t2, &x, &t2)) != MP_OKAY) { goto error; } + if ((err = mp_reduce(&t2, modulus, mu)) != MP_OKAY) { goto error; } + /* T1 = T1 * X */ + if ((err = mp_mul(&t1, &x, &t1)) != MP_OKAY) { goto error; } + if ((err = mp_reduce(&t1, modulus, mu)) != MP_OKAY) { goto error; } + + /* X = Y*Y */ + if ((err = mp_sqr(&y, &x)) != MP_OKAY) { goto error; } + if ((err = mp_reduce(&x, modulus, mu)) != MP_OKAY) { goto error; } + /* X = X - T2 */ + if ((err = mp_sub(&x, &t2, &x)) != MP_OKAY) { goto error; } + if (mp_cmp_d(&x, 0) == MP_LT) { + if ((err = mp_add(&x, modulus, &x)) != MP_OKAY) { goto error; } } - if ((err = mp_mul(&s, &tmp, &s)) != MP_OKAY) { goto error; } /* s = s * tmp mod modulus */ - if ((err = mp_reduce(&s, modulus, mu)) != MP_OKAY) { goto error; } - /* Xr = s^2 - Xp - Xq */ - if ((err = mp_sqr(&s, &tmp)) != MP_OKAY) { goto error; } /* tmp = s^2 mod modulus */ - if ((err = mp_reduce(&tmp, modulus, mu)) != MP_OKAY) { goto error; } - if ((err = mp_sub(&tmp, &P->x, &tmp)) != MP_OKAY) { goto error; } /* tmp = tmp - Px */ - if ((err = mp_sub(&tmp, &Q->x, &tmpx)) != MP_OKAY) { goto error; } /* tmpx = tmp - Qx */ + /* T2 = T2 - X */ + if ((err = mp_sub(&t2, &x, &t2)) != MP_OKAY) { goto error; } + if (mp_cmp_d(&t2, 0) == MP_LT) { + if ((err = mp_add(&t2, modulus, &t2)) != MP_OKAY) { goto error; } + } + /* T2 = T2 - X */ + if ((err = mp_sub(&t2, &x, &t2)) != MP_OKAY) { goto error; } + if (mp_cmp_d(&t2, 0) == MP_LT) { + if ((err = mp_add(&t2, modulus, &t2)) != MP_OKAY) { goto error; } + } + /* T2 = T2 * Y */ + if ((err = mp_mul(&t2, &y, &t2)) != MP_OKAY) { goto error; } + if ((err = mp_reduce(&t2, modulus, mu)) != MP_OKAY) { goto error; } + /* Y = T2 - T1 */ + if ((err = mp_sub(&t2, &t1, &y)) != MP_OKAY) { goto error; } + if (mp_cmp_d(&y, 0) == MP_LT) { + if ((err = mp_add(&y, modulus, &y)) != MP_OKAY) { goto error; } + } + /* Y = Y/2 */ + if (mp_isodd(&y)) { + if ((err = mp_add(&y, modulus, &y)) != MP_OKAY) { goto error; } + } + if ((err = mp_div_2(&y, &y)) != MP_OKAY) { goto error; } - /* Yr = -Yp + s(Xp - Xr) */ - if ((err = mp_sub(&P->x, &tmpx, &tmp)) != MP_OKAY) { goto error; } /* tmp = Px - tmpx */ - if ((err = mp_mul(&tmp, &s, &tmp)) != MP_OKAY) { goto error; } /* tmp = tmp * s */ - if ((err = mp_submod(&tmp, &P->y, modulus, &R->y)) != MP_OKAY) { goto error; } /* Ry = tmp - Py mod modulus */ - if ((err = mp_mod(&tmpx, modulus, &R->x)) != MP_OKAY) { goto error; } /* Rx = tmpx mod modulus */ + if ((err = mp_copy(&x, &R->x)) != MP_OKAY) { goto error; } + if ((err = mp_copy(&y, &R->y)) != MP_OKAY) { goto error; } + if ((err = mp_copy(&z, &R->z)) != MP_OKAY) { goto error; } err = CRYPT_OK; goto done; error: err = mpi_to_ltc_error(err); done: - mp_clear_multi(&s, &tmpx, &tmp, NULL); + mp_clear_multi(&t1, &t2, &x, &y, &z, NULL); return err; } @@ -408,6 +589,7 @@ static int ecc_mulmod(mp_int *k, ecc_point *G, ecc_point *R, mp_int *modulus) /* tG = G */ if ((err = mp_copy(&G->x, &tG->x)) != MP_OKAY) { goto error; } if ((err = mp_copy(&G->y, &tG->y)) != MP_OKAY) { goto error; } + if ((err = mp_copy(&G->z, &tG->z)) != MP_OKAY) { goto error; } /* calc the M tab, which holds kG for k==8..15 */ /* M[0] == 8G */ @@ -464,6 +646,7 @@ static int ecc_mulmod(mp_int *k, ecc_point *G, ecc_point *R, mp_int *modulus) /* R = kG [k = first window] */ if ((err = mp_copy(&M[bitbuf-8]->x, &R->x)) != MP_OKAY) { goto error; } if ((err = mp_copy(&M[bitbuf-8]->y, &R->y)) != MP_OKAY) { goto error; } + if ((err = mp_copy(&M[bitbuf-8]->z, &R->z)) != MP_OKAY) { goto error; } first = 0; } else { /* normal window */ @@ -497,6 +680,7 @@ static int ecc_mulmod(mp_int *k, ecc_point *G, ecc_point *R, mp_int *modulus) /* first add, so copy */ if ((err = mp_copy(&tG->x, &R->x)) != MP_OKAY) { goto error; } if ((err = mp_copy(&tG->y, &R->y)) != MP_OKAY) { goto error; } + if ((err = mp_copy(&tG->z, &R->z)) != MP_OKAY) { goto error; } first = 0; } else { /* then add */ @@ -505,7 +689,9 @@ static int ecc_mulmod(mp_int *k, ecc_point *G, ecc_point *R, mp_int *modulus) } } } - err = CRYPT_OK; + + /* map R back from projective space */ + err = ecc_map(R, modulus, &mu); goto done; error: err = mpi_to_ltc_error(err); @@ -566,6 +752,7 @@ int ecc_test(void) if ((err = mp_read_radix(&G->x, (char *)sets[i].Gx, 64)) != MP_OKAY) { goto error; } if ((err = mp_read_radix(&G->y, (char *)sets[i].Gy, 64)) != MP_OKAY) { goto error; } + mp_set(&G->z, 1); /* then we should have G == (order + 1)G */ if ((err = mp_add_d(&order, 1, &order)) != MP_OKAY) { goto error; } @@ -629,9 +816,8 @@ 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; - LTC_ARGCHK(keysize <= ECC_MAXSIZE); - if (sets[x].size == 0) { + if (keysize > ECC_MAXSIZE || sets[x].size == 0) { return CRYPT_INVALID_KEYSIZE; } key->idx = x; @@ -650,13 +836,13 @@ int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key) } /* setup the key variables */ - if ((err = mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->k, &prime, NULL)) != MP_OKAY) { + if ((err = mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, &prime, NULL)) != MP_OKAY) { err = mpi_to_ltc_error(err); goto LBL_ERR; } base = new_point(); if (base == NULL) { - mp_clear_multi(&key->pubkey.x, &key->pubkey.y, &key->k, &prime, NULL); + mp_clear_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, &prime, NULL); err = CRYPT_MEM; goto LBL_ERR; } @@ -665,6 +851,7 @@ int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key) if ((err = mp_read_radix(&prime, (char *)sets[key->idx].prime, 64)) != MP_OKAY) { goto error; } if ((err = mp_read_radix(&base->x, (char *)sets[key->idx].Gx, 64)) != MP_OKAY) { goto error; } if ((err = mp_read_radix(&base->y, (char *)sets[key->idx].Gy, 64)) != MP_OKAY) { goto error; } + mp_set(&base->z, 1); if ((err = mp_read_unsigned_bin(&key->k, (unsigned char *)buf, keysize)) != MP_OKAY) { goto error; } /* make the public key */ @@ -675,6 +862,7 @@ int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key) if ((err = mp_shrink(&key->k)) != MP_OKAY) { goto error; } if ((err = mp_shrink(&key->pubkey.x)) != MP_OKAY) { goto error; } if ((err = mp_shrink(&key->pubkey.y)) != MP_OKAY) { goto error; } + if ((err = mp_shrink(&key->pubkey.z)) != MP_OKAY) { goto error; } /* free up ram */ err = CRYPT_OK; @@ -701,7 +889,7 @@ LBL_ERR2: void ecc_free(ecc_key *key) { LTC_ARGCHK(key != NULL); - mp_clear_multi(&key->pubkey.x, &key->pubkey.y, &key->k, NULL); + mp_clear_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, NULL); } static int compress_y_point(ecc_point *pt, int idx, int *result) @@ -865,7 +1053,7 @@ int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key) } /* init key */ - if (mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->k, NULL) != MP_OKAY) { + if (mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, NULL) != MP_OKAY) { return CRYPT_MEM; } @@ -911,9 +1099,12 @@ int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key) mp_clear(&key->k); } + /* z is always 1 */ + mp_set(&key->pubkey.z, 1); + return CRYPT_OK; error: - mp_clear_multi(&key->pubkey.x, &key->pubkey.y, &key->k, NULL); + mp_clear_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, NULL); return err; } diff --git a/src/pk/ecc/ecc_sys.c b/src/pk/ecc/ecc_sys.c index 9a92572..d5576f6 100644 --- a/src/pk/ecc/ecc_sys.c +++ b/src/pk/ecc/ecc_sys.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ /** @@ -520,9 +520,13 @@ int ecc_verify_hash(const unsigned char *sig, unsigned long siglen, /* get bA + Y */ if ((err = add_point(&pubkey.pubkey, &key->pubkey, &pubkey.pubkey, &p, &mu)) != CRYPT_OK) { goto done; } + /* we have to transform it */ + if ((err = ecc_map(&pubkey.pubkey, &p, &mu)) != CRYPT_OK) { goto done; } + /* get mG */ if ((err = mp_read_radix(&mG->x, (char *)sets[key->idx].Gx, 64)) != MP_OKAY) { goto error; } if ((err = mp_read_radix(&mG->y, (char *)sets[key->idx].Gy, 64)) != MP_OKAY) { goto error; } + mp_set(&mG->z, 1); if ((err = ecc_mulmod(&m, mG, mG, &p)) != CRYPT_OK) { goto done; } /* compare mG to bA + Y */ diff --git a/src/pk/packet_store_header.c b/src/pk/packet_store_header.c index c86f00e..a2442cc 100644 --- a/src/pk/packet_store_header.c +++ b/src/pk/packet_store_header.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/pk/packet_valid_header.c b/src/pk/packet_valid_header.c index 39eb0bb..b2eb9c9 100644 --- a/src/pk/packet_valid_header.c +++ b/src/pk/packet_valid_header.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/pk/pkcs1/pkcs_1_i2osp.c b/src/pk/pkcs1/pkcs_1_i2osp.c index a1ce7e8..7f13626 100644 --- a/src/pk/pkcs1/pkcs_1_i2osp.c +++ b/src/pk/pkcs1/pkcs_1_i2osp.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/pk/pkcs1/pkcs_1_mgf1.c b/src/pk/pkcs1/pkcs_1_mgf1.c index 48ec7b0..0fe177f 100644 --- a/src/pk/pkcs1/pkcs_1_mgf1.c +++ b/src/pk/pkcs1/pkcs_1_mgf1.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" @@ -30,7 +30,8 @@ int pkcs_1_mgf1(const unsigned char *seed, unsigned long seedlen, int hash_idx, unsigned char *mask, unsigned long masklen) { - unsigned long hLen, counter, x; + unsigned long hLen, x; + ulong32 counter; int err; hash_state *md; unsigned char *buf; diff --git a/src/pk/pkcs1/pkcs_1_oaep_decode.c b/src/pk/pkcs1/pkcs_1_oaep_decode.c index 32a1e36..82862c1 100644 --- a/src/pk/pkcs1/pkcs_1_oaep_decode.c +++ b/src/pk/pkcs1/pkcs_1_oaep_decode.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" @@ -55,6 +55,11 @@ int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen, hLen = hash_descriptor[hash_idx].hashsize; modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0); + /* test hash/message size */ + if ((2*hLen >= (modulus_len - 2)) || (msglen != modulus_len)) { + return CRYPT_PK_INVALID_SIZE; + } + /* allocate ram for DB/mask/salt of size modulus_len */ DB = XMALLOC(modulus_len); mask = XMALLOC(modulus_len); @@ -72,13 +77,6 @@ int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen, return CRYPT_MEM; } - - /* test message size */ - if (msglen != modulus_len) { - err = CRYPT_PK_INVALID_SIZE; - goto LBL_ERR; - } - /* ok so it's now in the form 0x00 || maskedseed || maskedDB diff --git a/src/pk/pkcs1/pkcs_1_oaep_encode.c b/src/pk/pkcs1/pkcs_1_oaep_encode.c index 63fc1c8..7afea60 100644 --- a/src/pk/pkcs1/pkcs_1_oaep_encode.c +++ b/src/pk/pkcs1/pkcs_1_oaep_encode.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" @@ -58,6 +58,11 @@ int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen, hLen = hash_descriptor[hash_idx].hashsize; modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0); + /* test message size */ + if ((2*hLen >= (modulus_len - 2)) || (msglen > (modulus_len - 2*hLen - 2))) { + return CRYPT_PK_INVALID_SIZE; + } + /* allocate ram for DB/mask/salt of size modulus_len */ DB = XMALLOC(modulus_len); mask = XMALLOC(modulus_len); @@ -75,12 +80,6 @@ int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen, return CRYPT_MEM; } - /* test message size */ - if (msglen > (modulus_len - 2*hLen - 2)) { - err = CRYPT_PK_INVALID_SIZE; - goto LBL_ERR; - } - /* get lhash */ /* DB == lhash || PS || 0x01 || M, PS == k - mlen - 2hlen - 2 zeroes */ x = modulus_len; diff --git a/src/pk/pkcs1/pkcs_1_os2ip.c b/src/pk/pkcs1/pkcs_1_os2ip.c index 4e786ad..db6b58c 100644 --- a/src/pk/pkcs1/pkcs_1_os2ip.c +++ b/src/pk/pkcs1/pkcs_1_os2ip.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/pk/pkcs1/pkcs_1_pss_decode.c b/src/pk/pkcs1/pkcs_1_pss_decode.c index 6ea2e91..a19e7d8 100644 --- a/src/pk/pkcs1/pkcs_1_pss_decode.c +++ b/src/pk/pkcs1/pkcs_1_pss_decode.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" @@ -53,6 +53,12 @@ int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen, hLen = hash_descriptor[hash_idx].hashsize; modulus_len = (modulus_bitlen>>3) + (modulus_bitlen & 7 ? 1 : 0); + /* check sizes */ + if ((saltlen > modulus_len) || + (modulus_len < hLen + saltlen + 2) || (siglen != modulus_len)) { + return CRYPT_PK_INVALID_SIZE; + } + /* allocate ram for DB/mask/salt/hash of size modulus_len */ DB = XMALLOC(modulus_len); mask = XMALLOC(modulus_len); @@ -74,13 +80,6 @@ int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen, return CRYPT_MEM; } - /* check sizes */ - if ((saltlen > modulus_len) || - (modulus_len < hLen + saltlen + 2) || (siglen != modulus_len)) { - err = CRYPT_INVALID_ARG; - goto LBL_ERR; - } - /* ensure the 0xBC byte */ if (sig[siglen-1] != 0xBC) { err = CRYPT_OK; diff --git a/src/pk/pkcs1/pkcs_1_pss_encode.c b/src/pk/pkcs1/pkcs_1_pss_encode.c index e5adf5b..58a03d5 100644 --- a/src/pk/pkcs1/pkcs_1_pss_encode.c +++ b/src/pk/pkcs1/pkcs_1_pss_encode.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" @@ -56,6 +56,11 @@ int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen, hLen = hash_descriptor[hash_idx].hashsize; modulus_len = (modulus_bitlen>>3) + (modulus_bitlen & 7 ? 1 : 0); + /* check sizes */ + if ((saltlen > modulus_len) || (modulus_len < hLen + saltlen + 2)) { + return CRYPT_PK_INVALID_SIZE; + } + /* allocate ram for DB/mask/salt/hash of size modulus_len */ DB = XMALLOC(modulus_len); mask = XMALLOC(modulus_len); @@ -78,12 +83,6 @@ int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen, } - /* check sizes */ - if ((saltlen > modulus_len) || (modulus_len < hLen + saltlen + 2)) { - err = CRYPT_INVALID_ARG; - goto LBL_ERR; - } - /* generate random salt */ if (saltlen > 0) { if (prng_descriptor[prng_idx].read(salt, saltlen, prng) != saltlen) { diff --git a/src/pk/pkcs1/pkcs_1_v15_es_decode.c b/src/pk/pkcs1/pkcs_1_v15_es_decode.c index 7f0631c..fc54845 100644 --- a/src/pk/pkcs1/pkcs_1_v15_es_decode.c +++ b/src/pk/pkcs1/pkcs_1_v15_es_decode.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/pk/pkcs1/pkcs_1_v15_es_encode.c b/src/pk/pkcs1/pkcs_1_v15_es_encode.c index 8e18f8f..b6ac429 100644 --- a/src/pk/pkcs1/pkcs_1_v15_es_encode.c +++ b/src/pk/pkcs1/pkcs_1_v15_es_encode.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/pk/pkcs1/pkcs_1_v15_sa_decode.c b/src/pk/pkcs1/pkcs_1_v15_sa_decode.c index 595a0aa..7cad021 100644 --- a/src/pk/pkcs1/pkcs_1_v15_sa_decode.c +++ b/src/pk/pkcs1/pkcs_1_v15_sa_decode.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/pk/pkcs1/pkcs_1_v15_sa_encode.c b/src/pk/pkcs1/pkcs_1_v15_sa_encode.c index 70c88cb..60c77ef 100644 --- a/src/pk/pkcs1/pkcs_1_v15_sa_encode.c +++ b/src/pk/pkcs1/pkcs_1_v15_sa_encode.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/pk/rsa/rsa_decrypt_key.c b/src/pk/rsa/rsa_decrypt_key.c index 95c94e3..3117715 100644 --- a/src/pk/rsa/rsa_decrypt_key.c +++ b/src/pk/rsa/rsa_decrypt_key.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/pk/rsa/rsa_encrypt_key.c b/src/pk/rsa/rsa_encrypt_key.c index ab5b978..891b43e 100644 --- a/src/pk/rsa/rsa_encrypt_key.c +++ b/src/pk/rsa/rsa_encrypt_key.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/pk/rsa/rsa_export.c b/src/pk/rsa/rsa_export.c index 1b52fac..951be70 100644 --- a/src/pk/rsa/rsa_export.c +++ b/src/pk/rsa/rsa_export.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" @@ -27,7 +27,7 @@ */ int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key) { - int err; + int err, x; LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); @@ -37,7 +37,15 @@ int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key if (!(key->type == PK_PRIVATE) && (type == PK_PRIVATE)) { return CRYPT_PK_INVALID_TYPE; } + if (*outlen < 4) { + return CRYPT_BUFFER_OVERFLOW; + } + /* Mental Note: push space for the header 0x30 0x82 LL LL (LL = length of packet EXcluding 4 bytes) + * we assume LL > 255 which is true since the smallest RSA key has a 128-byte modulus (1024-bit) + */ + *outlen -= 4; + if (type == PK_PRIVATE) { /* private key */ mp_int zero; @@ -50,17 +58,40 @@ int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key /* 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, + if ((err = der_put_multi_integer( + out+4, outlen, &zero, &key->N, &key->e, &key->d, &key->p, &key->q, &key->dP, - &key->dQ, &key->qP, NULL); + &key->dQ, &key->qP, NULL)) != CRYPT_OK) { + mp_clear(&zero); + return err; + } /* 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 ((err = der_put_multi_integer(out+4, outlen, &key->N, &key->e, NULL)) != CRYPT_OK) { + return err; + } } + + /* store the header */ + out[0] = 0x30; + if (*outlen < 256) { + /* shift the output up one byte if the header is only 3 bytes */ + for (x = 0; x < *outlen; x++) { + out[x+3] = out[x+4]; + } + out[1] = 0x81; + out[2] = (*outlen & 255); + *outlen += 3; + } else { + out[1] = 0x82; + out[2] = (*outlen >> 8) & 255; + out[3] = (*outlen & 255); + *outlen += 4; + } + return err; } #endif /* MRSA */ diff --git a/src/pk/rsa/rsa_exptmod.c b/src/pk/rsa/rsa_exptmod.c index e7f7c6a..fda6cbb 100644 --- a/src/pk/rsa/rsa_exptmod.c +++ b/src/pk/rsa/rsa_exptmod.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/pk/rsa/rsa_free.c b/src/pk/rsa/rsa_free.c index e828a72..85ade97 100644 --- a/src/pk/rsa/rsa_free.c +++ b/src/pk/rsa/rsa_free.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/pk/rsa/rsa_import.c b/src/pk/rsa/rsa_import.c index 2c96f6c..6ceac44 100644 --- a/src/pk/rsa/rsa_import.c +++ b/src/pk/rsa/rsa_import.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" @@ -26,7 +26,7 @@ */ int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key) { - unsigned long x; + unsigned long x, y; int err; LTC_ARGCHK(in != NULL); @@ -38,6 +38,35 @@ int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key) return mpi_to_ltc_error(err); } + /* check the header */ + if (inlen < 4) { + return CRYPT_INVALID_PACKET; + } + + /* should be 0x30 0x8{1|2} LL LL */ + if ((in[0] != 0x30) || ((in[1] != 0x81) && (in[1] != 0x82))) { + return CRYPT_INVALID_PACKET; + } + + /* ok all the ASN.1 params are fine so far, let's move up */ + x = ((unsigned long)in[2]); + y = 0; + if ((in[1] & 0x0f) == 2) { + x = (x << 8) + ((unsigned long)in[3]) + 1; + in += 1; + y = 1; + } + in += 3; /* advance input */ + x += 3; /* size of packet according to header */ + y += 3; /* used input */ + + if (x != inlen) { + return CRYPT_INVALID_PACKET; + } + + /* decrement inlen by the header size */ + inlen -= y; + /* 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) { diff --git a/src/pk/rsa/rsa_make_key.c b/src/pk/rsa/rsa_make_key.c index a37057b..9d49e3c 100644 --- a/src/pk/rsa/rsa_make_key.c +++ b/src/pk/rsa/rsa_make_key.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/pk/rsa/rsa_sign_hash.c b/src/pk/rsa/rsa_sign_hash.c index 70f6259..b86ad64 100644 --- a/src/pk/rsa/rsa_sign_hash.c +++ b/src/pk/rsa/rsa_sign_hash.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/pk/rsa/rsa_v15_decrypt_key.c b/src/pk/rsa/rsa_v15_decrypt_key.c index d29aa15..eb5fe7d 100644 --- a/src/pk/rsa/rsa_v15_decrypt_key.c +++ b/src/pk/rsa/rsa_v15_decrypt_key.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/pk/rsa/rsa_v15_encrypt_key.c b/src/pk/rsa/rsa_v15_encrypt_key.c index 4aaa4a7..d422f67 100644 --- a/src/pk/rsa/rsa_v15_encrypt_key.c +++ b/src/pk/rsa/rsa_v15_encrypt_key.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/pk/rsa/rsa_v15_sign_hash.c b/src/pk/rsa/rsa_v15_sign_hash.c index 4571c68..7e9b350 100644 --- a/src/pk/rsa/rsa_v15_sign_hash.c +++ b/src/pk/rsa/rsa_v15_sign_hash.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/pk/rsa/rsa_v15_verify_hash.c b/src/pk/rsa/rsa_v15_verify_hash.c index bdf6bac..e742cba 100644 --- a/src/pk/rsa/rsa_v15_verify_hash.c +++ b/src/pk/rsa/rsa_v15_verify_hash.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/pk/rsa/rsa_verify_hash.c b/src/pk/rsa/rsa_verify_hash.c index 910f093..7072083 100644 --- a/src/pk/rsa/rsa_verify_hash.c +++ b/src/pk/rsa/rsa_verify_hash.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/prngs/fortuna.c b/src/prngs/fortuna.c index fc054ee..4548a90 100644 --- a/src/prngs/fortuna.c +++ b/src/prngs/fortuna.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/prngs/rc4.c b/src/prngs/rc4.c index 63a4c55..750c38b 100644 --- a/src/prngs/rc4.c +++ b/src/prngs/rc4.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/prngs/rng_get_bytes.c b/src/prngs/rng_get_bytes.c index cac4acf..8519e0a 100644 --- a/src/prngs/rng_get_bytes.c +++ b/src/prngs/rng_get_bytes.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/prngs/rng_make_prng.c b/src/prngs/rng_make_prng.c index 49195d3..94132e7 100644 --- a/src/prngs/rng_make_prng.c +++ b/src/prngs/rng_make_prng.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/prngs/sober128.c b/src/prngs/sober128.c index 715742d..48667bd 100644 --- a/src/prngs/sober128.c +++ b/src/prngs/sober128.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/prngs/sprng.c b/src/prngs/sprng.c index e45d674..dce8347 100644 --- a/src/prngs/sprng.c +++ b/src/prngs/sprng.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" diff --git a/src/prngs/yarrow.c b/src/prngs/yarrow.c index cf5458a..1582856 100644 --- a/src/prngs/yarrow.c +++ b/src/prngs/yarrow.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org */ #include "tomcrypt.h" @@ -222,9 +222,11 @@ unsigned long yarrow_read(unsigned char *out, unsigned long outlen, prng_state * int yarrow_done(prng_state *prng) { LTC_ARGCHK(prng != NULL); + /* call cipher done when we invent one ;-) */ - return CRYPT_OK; + /* we invented one */ + return ctr_done(&prng->yarrow.ctr); } /** diff --git a/demos/test/base64_test.c b/testprof/base64_test.c similarity index 86% rename from demos/test/base64_test.c rename to testprof/base64_test.c index b02c1a2..e93ebef 100644 --- a/demos/test/base64_test.c +++ b/testprof/base64_test.c @@ -1,4 +1,4 @@ -#include "test.h" +#include int base64_test(void) { @@ -6,7 +6,7 @@ int base64_test(void) unsigned long x, l1, l2; for (x = 0; x < 64; x++) { - yarrow_read(in, x, &test_yarrow); + yarrow_read(in, x, &yarrow_prng); l1 = sizeof(out); DO(base64_encode(in, x, out, &l1)); l2 = sizeof(tmp); diff --git a/demos/test/cipher_hash_test.c b/testprof/cipher_hash_test.c similarity index 97% rename from demos/test/cipher_hash_test.c rename to testprof/cipher_hash_test.c index 2737623..d2f3bfc 100644 --- a/demos/test/cipher_hash_test.c +++ b/testprof/cipher_hash_test.c @@ -1,6 +1,6 @@ /* test the ciphers and hashes using their built-in self-tests */ -#include "test.h" +#include int cipher_hash_test(void) { diff --git a/demos/test/der_tests.c b/testprof/der_tests.c similarity index 96% rename from demos/test/der_tests.c rename to testprof/der_tests.c index dd17f31..fe8eb00 100644 --- a/demos/test/der_tests.c +++ b/testprof/der_tests.c @@ -1,4 +1,4 @@ -#include "test.h" +#include #ifndef LTC_DER @@ -19,7 +19,7 @@ int der_tests(void) 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) { + if (yarrow_read(buf[0], z, &yarrow_prng) != z) { printf("Failed to read %lu bytes from yarrow\n", z); return 1; } diff --git a/demos/test/dh_tests.c b/testprof/dh_tests.c similarity index 84% rename from demos/test/dh_tests.c rename to testprof/dh_tests.c index 6977c58..feb74ac 100644 --- a/demos/test/dh_tests.c +++ b/testprof/dh_tests.c @@ -1,4 +1,4 @@ -#include "test.h" +#include #ifdef MDH @@ -12,8 +12,8 @@ int dh_tests (void) DO(dh_test()); /* make up two keys */ - DO(dh_make_key (&test_yarrow, find_prng ("yarrow"), 512, &usera)); - DO(dh_make_key (&test_yarrow, find_prng ("yarrow"), 512, &userb)); + DO(dh_make_key (&yarrow_prng, find_prng ("yarrow"), 512, &usera)); + DO(dh_make_key (&yarrow_prng, find_prng ("yarrow"), 512, &userb)); /* make the shared secret */ x = 4096; @@ -52,12 +52,12 @@ int dh_tests (void) dh_free (&userb); /* test encrypt_key */ - dh_make_key (&test_yarrow, find_prng ("yarrow"), 512, &usera); + dh_make_key (&yarrow_prng, find_prng ("yarrow"), 512, &usera); for (x = 0; x < 16; x++) { buf[0][x] = x; } y = sizeof (buf[1]); - DO(dh_encrypt_key (buf[0], 16, buf[1], &y, &test_yarrow, find_prng ("yarrow"), find_hash ("md5"), &usera)); + DO(dh_encrypt_key (buf[0], 16, buf[1], &y, &yarrow_prng, find_prng ("yarrow"), find_hash ("md5"), &usera)); zeromem (buf[0], sizeof (buf[0])); x = sizeof (buf[0]); DO(dh_decrypt_key (buf[1], y, buf[0], &x, &usera)); @@ -76,7 +76,7 @@ int dh_tests (void) buf[0][x] = x; } x = sizeof (buf[1]); - DO(dh_sign_hash (buf[0], 16, buf[1], &x, &test_yarrow , find_prng ("yarrow"), &usera)); + DO(dh_sign_hash (buf[0], 16, buf[1], &x, &yarrow_prng , find_prng ("yarrow"), &usera)); DO(dh_verify_hash (buf[1], x, buf[0], 16, &stat, &usera)); buf[0][0] ^= 1; DO(dh_verify_hash (buf[1], x, buf[0], 16, &stat2, &usera)); diff --git a/demos/test/dsa_test.c b/testprof/dsa_test.c similarity index 90% rename from demos/test/dsa_test.c rename to testprof/dsa_test.c index c5eeb6d..cd2e89a 100644 --- a/demos/test/dsa_test.c +++ b/testprof/dsa_test.c @@ -1,4 +1,4 @@ -#include "test.h" +#include #ifdef MDSA @@ -10,7 +10,7 @@ int dsa_test(void) dsa_key key, key2; /* make a random key */ - DO(dsa_make_key(&test_yarrow, find_prng("yarrow"), 20, 128, &key)); + DO(dsa_make_key(&yarrow_prng, find_prng("yarrow"), 20, 128, &key)); /* verify it */ DO(dsa_verify_key(&key, &stat1)); @@ -18,7 +18,7 @@ int dsa_test(void) /* sign the message */ x = sizeof(out); - DO(dsa_sign_hash(msg, sizeof(msg), out, &x, &test_yarrow, find_prng("yarrow"), &key)); + DO(dsa_sign_hash(msg, sizeof(msg), out, &x, &yarrow_prng, find_prng("yarrow"), &key)); /* verify it once */ DO(dsa_verify_hash(out, x, msg, sizeof(msg), &stat1, &key)); diff --git a/demos/test/ecc_test.c b/testprof/ecc_test.c similarity index 84% rename from demos/test/ecc_test.c rename to testprof/ecc_test.c index 9121f92..0b37ba2 100644 --- a/demos/test/ecc_test.c +++ b/testprof/ecc_test.c @@ -1,4 +1,4 @@ -#include "test.h" +#include #ifdef MECC @@ -12,8 +12,8 @@ int ecc_tests (void) DO(ecc_test ()); /* make up two keys */ - DO(ecc_make_key (&test_yarrow, find_prng ("yarrow"), 65, &usera)); - DO(ecc_make_key (&test_yarrow, find_prng ("yarrow"), 65, &userb)); + DO(ecc_make_key (&yarrow_prng, find_prng ("yarrow"), 65, &usera)); + DO(ecc_make_key (&yarrow_prng, find_prng ("yarrow"), 65, &userb)); /* make the shared secret */ x = 4096; @@ -55,7 +55,7 @@ int ecc_tests (void) ecc_free (&userb); /* test encrypt_key */ - DO(ecc_make_key (&test_yarrow, find_prng ("yarrow"), 65, &usera)); + DO(ecc_make_key (&yarrow_prng, find_prng ("yarrow"), 65, &usera)); /* export key */ x = sizeof(buf[0]); @@ -69,7 +69,7 @@ int ecc_tests (void) buf[0][x] = x; } y = sizeof (buf[1]); - DO(ecc_encrypt_key (buf[0], 32, buf[1], &y, &test_yarrow, find_prng ("yarrow"), find_hash ("sha256"), &pubKey)); + DO(ecc_encrypt_key (buf[0], 32, buf[1], &y, &yarrow_prng, find_prng ("yarrow"), find_hash ("sha256"), &pubKey)); zeromem (buf[0], sizeof (buf[0])); x = sizeof (buf[0]); DO(ecc_decrypt_key (buf[1], y, buf[0], &x, &privKey)); @@ -87,12 +87,12 @@ int ecc_tests (void) buf[0][x] = x; } x = sizeof (buf[1]); - DO(ecc_sign_hash (buf[0], 16, buf[1], &x, &test_yarrow, find_prng ("yarrow"), &privKey)); + DO(ecc_sign_hash (buf[0], 16, buf[1], &x, &yarrow_prng, find_prng ("yarrow"), &privKey)); DO(ecc_verify_hash (buf[1], x, buf[0], 16, &stat, &pubKey)); buf[0][0] ^= 1; DO(ecc_verify_hash (buf[1], x, buf[0], 16, &stat2, &privKey)); if (!(stat == 1 && stat2 == 0)) { - printf("ecc_verify_hash failed"); + printf("ecc_verify_hash failed %d, %d, ", stat, stat2); return 1; } ecc_free (&usera); diff --git a/testprof/mac_test.c b/testprof/mac_test.c new file mode 100644 index 0000000..b076d7b --- /dev/null +++ b/testprof/mac_test.c @@ -0,0 +1,31 @@ +/* test pmac/omac/hmac */ +#include + +int mac_test(void) +{ +#ifdef HMAC + DO(hmac_test()); +#endif +#ifdef PMAC + DO(pmac_test()); +#endif +#ifdef OMAC + DO(omac_test()); +#endif +#ifdef EAX_MODE + DO(eax_test()); +#endif +#ifdef OCB_MODE + DO(ocb_test()); +#endif +#ifdef CCM_MODE + DO(ccm_test()); +#endif +#ifdef GCM_MODE + DO(gcm_test()); +#endif +#ifdef PELICAN + DO(pelican_test()); +#endif + return 0; +} diff --git a/testprof/makefile b/testprof/makefile new file mode 100644 index 0000000..f4be577 --- /dev/null +++ b/testprof/makefile @@ -0,0 +1,15 @@ +CFLAGS += -I../src/headers -I./ -Wall -W + +OBJECTS = base64_test.o cipher_hash_test.o der_tests.o dh_tests.o \ +dsa_test.o ecc_test.o mac_test.o modes_test.o pkcs_1_test.o rsa_test.o \ +store_test.o test.o x86_prof.o + +default: libtomcrypt_prof.a + +libtomcrypt_prof.a: $(OBJECTS) + $(AR) $(ARFLAGS) libtomcrypt_prof.a $(OBJECTS) + ranlib libtomcrypt_prof.a + +clean: + rm -f *.o *.a + diff --git a/testprof/makefile.icc b/testprof/makefile.icc new file mode 100644 index 0000000..c9226fb --- /dev/null +++ b/testprof/makefile.icc @@ -0,0 +1,15 @@ +CFLAGS += -I../src/headers -I./ -O3 -xP -ip +CC=icc + +OBJECTS = base64_test.o cipher_hash_test.o der_tests.o dh_tests.o \ +dsa_test.o ecc_test.o mac_test.o modes_test.o pkcs_1_test.o rsa_test.o \ +store_test.o test.o x86_prof.o + +default: libtomcrypt_prof.a + +libtomcrypt_prof.a: $(OBJECTS) + $(AR) $(ARFLAGS) libtomcrypt_prof.a $(OBJECTS) + +clean: + rm -f *.o *.a + diff --git a/testprof/makefile.msvc b/testprof/makefile.msvc new file mode 100644 index 0000000..6e15ffb --- /dev/null +++ b/testprof/makefile.msvc @@ -0,0 +1,10 @@ +CFLAGS = /I../src/headers/ /I./ /Ox /DWIN32 /W3 /Fo$@ + +OBJECTS=base64_test.obj cipher_hash_test.obj der_tests.obj dh_tests.obj \ +dsa_test.obj ecc_test.obj mac_test.obj modes_test.obj pkcs_1_test.obj \ +rsa_test.obj store_test.obj test.obj x86_prof.obj + +tomcrypt_prof.lib: $(OBJECTS) + lib /out:tomcrypt_prof.lib $(OBJECTS) + + diff --git a/testprof/makefile.shared b/testprof/makefile.shared new file mode 100644 index 0000000..b4219f0 --- /dev/null +++ b/testprof/makefile.shared @@ -0,0 +1,15 @@ +CC=libtool --mode=compile gcc + +CFLAGS += -I../src/headers -I./ -O3 -fomit-frame-pointer -funroll-loops -Wall -W + +OBJECTS = base64_test.o cipher_hash_test.o der_tests.o dh_tests.o \ +dsa_test.o ecc_test.o mac_test.o modes_test.o pkcs_1_test.o rsa_test.o \ +store_test.o test.o x86_prof.o + +default: $(LIBNAME) + +$(LIBNAME): $(OBJECTS) + libtool --silent --mode=link gcc $(CFLAGS) `find . -type f | grep "[.]lo" | xargs` -o libtomcrypt_prof.la -rpath $(LIBPATH) -version-info $(VERSION) + libtool --silent --mode=link gcc $(CFLAGS) `find . -type f | grep "[.]o" | xargs` -o libtomcrypt_prof.a + ranlib libtomcrypt_prof.a + libtool --silent --mode=install install -c libtomcrypt_prof.la $(LIBPATH)/libtomcrypt_prof.la diff --git a/demos/test/modes_test.c b/testprof/modes_test.c similarity index 84% rename from demos/test/modes_test.c rename to testprof/modes_test.c index 7494b4d..46beb8a 100644 --- a/demos/test/modes_test.c +++ b/testprof/modes_test.c @@ -1,10 +1,10 @@ /* test CFB/OFB/CBC modes */ -#include "test.h" +#include int modes_test(void) { unsigned char pt[64], ct[64], tmp[64], key[16], iv[16], iv2[16]; - int x, cipher_idx; + int cipher_idx; symmetric_CBC cbc; symmetric_CFB cfb; symmetric_OFB ofb; @@ -12,9 +12,9 @@ int modes_test(void) unsigned long l; /* make a random pt, key and iv */ - yarrow_read(pt, 64, &test_yarrow); - yarrow_read(key, 16, &test_yarrow); - yarrow_read(iv, 16, &test_yarrow); + yarrow_read(pt, 64, &yarrow_prng); + yarrow_read(key, 16, &yarrow_prng); + yarrow_read(iv, 16, &yarrow_prng); /* get idx of AES handy */ cipher_idx = find_cipher("aes"); @@ -23,6 +23,7 @@ int modes_test(void) return 1; } +#ifdef CBC /* test CBC mode */ /* encode the block */ DO(cbc_start(cipher_idx, iv, key, 16, 0, &cbc)); @@ -32,21 +33,19 @@ int modes_test(void) printf("cbc_getiv failed"); return 1; } - for (x = 0; x < 4; x++) { - DO(cbc_encrypt(pt+x*16, ct+x*16, &cbc)); - } + DO(cbc_encrypt(pt, ct, 64, &cbc)); /* decode the block */ DO(cbc_setiv(iv2, l, &cbc)); zeromem(tmp, sizeof(tmp)); - for (x = 0; x < 4; x++) { - DO(cbc_decrypt(ct+x*16, tmp+x*16, &cbc)); - } + DO(cbc_decrypt(ct, tmp, 64, &cbc)); if (memcmp(tmp, pt, 64) != 0) { printf("CBC failed"); return 1; } - +#endif + +#ifdef CFB /* test CFB mode */ /* encode the block */ DO(cfb_start(cipher_idx, iv, key, 16, 0, &cfb)); @@ -67,7 +66,9 @@ int modes_test(void) printf("CFB failed"); return 1; } +#endif +#ifdef OFB /* test OFB mode */ /* encode the block */ DO(ofb_start(cipher_idx, iv, key, 16, 0, &ofb)); @@ -87,7 +88,9 @@ int modes_test(void) printf("OFB failed"); return 1; } - +#endif + +#ifdef CTR /* test CTR mode */ /* encode the block */ DO(ctr_start(cipher_idx, iv, key, 16, 0, &ctr)); @@ -97,16 +100,17 @@ int modes_test(void) printf("ctr_getiv failed"); return 1; } - DO(ctr_encrypt(pt, ct, 64, &ctr)); + DO(ctr_encrypt(pt, ct, 57, &ctr)); /* decode the block */ DO(ctr_setiv(iv2, l, &ctr)); zeromem(tmp, sizeof(tmp)); - DO(ctr_decrypt(ct, tmp, 64, &ctr)); - if (memcmp(tmp, pt, 64) != 0) { + DO(ctr_decrypt(ct, tmp, 57, &ctr)); + if (memcmp(tmp, pt, 57) != 0) { printf("CTR failed"); return 1; } +#endif return 0; } diff --git a/demos/test/pkcs_1_test.c b/testprof/pkcs_1_test.c similarity index 94% rename from demos/test/pkcs_1_test.c rename to testprof/pkcs_1_test.c index 52af7b6..40cf630 100644 --- a/demos/test/pkcs_1_test.c +++ b/testprof/pkcs_1_test.c @@ -1,4 +1,4 @@ -#include "test.h" +#include #ifdef PKCS_1 @@ -31,7 +31,7 @@ int pkcs_1_test(void) /* PKCS v1.5 testing (encryption) */ l1 = sizeof(buf[1]); - DO(pkcs_1_v15_es_encode(buf[0], l3, modlen, &test_yarrow, prng_idx, buf[1], &l1)); + DO(pkcs_1_v15_es_encode(buf[0], l3, modlen, &yarrow_prng, prng_idx, buf[1], &l1)); DO(pkcs_1_v15_es_decode(buf[1], l1, modlen, buf[2], l3, &res1)); if (res1 != 1 || memcmp(buf[0], buf[2], l3)) { printf("pkcs v1.5 encrypt failed %d, %lu, %lu ", res1, l1, l3); @@ -64,7 +64,7 @@ int pkcs_1_test(void) /* encode it */ l1 = sizeof(buf[1]); - DO(pkcs_1_oaep_encode(buf[0], l3, lparam, lparamlen, modlen, &test_yarrow, prng_idx, hash_idx, buf[1], &l1)); + DO(pkcs_1_oaep_encode(buf[0], l3, lparam, lparamlen, modlen, &yarrow_prng, prng_idx, hash_idx, buf[1], &l1)); /* decode it */ l2 = sizeof(buf[2]); @@ -86,7 +86,7 @@ int pkcs_1_test(void) /* test PSS */ l1 = sizeof(buf[1]); - DO(pkcs_1_pss_encode(buf[0], l3, saltlen, &test_yarrow, prng_idx, hash_idx, modlen, buf[1], &l1)); + DO(pkcs_1_pss_encode(buf[0], l3, saltlen, &yarrow_prng, prng_idx, hash_idx, modlen, buf[1], &l1)); DO(pkcs_1_pss_decode(buf[0], l3, buf[1], l1, saltlen, hash_idx, modlen, &res1)); buf[0][i1 = abs(rand()) % l3] ^= 1; diff --git a/demos/test/rsa_test.c b/testprof/rsa_test.c similarity index 81% rename from demos/test/rsa_test.c rename to testprof/rsa_test.c index 4ff1962..f114e49 100644 --- a/demos/test/rsa_test.c +++ b/testprof/rsa_test.c @@ -1,4 +1,4 @@ -#include "test.h" +#include #ifdef MRSA @@ -19,20 +19,56 @@ int rsa_test(void) return 1; } - /* make a random key */ - DO(rsa_make_key(&test_yarrow, prng_idx, 1024/8, 65537, &key)); + /* make 10 random key */ + for (cnt = 0; cnt < 10; cnt++) { + DO(rsa_make_key(&yarrow_prng, prng_idx, 1024/8, 65537, &key)); + if (mp_count_bits(&key.N) != 1024) { + printf("rsa_1024 key modulus has %d bits\n", mp_count_bits(&key.N)); + +len = mp_unsigned_bin_size(&key.N); +mp_to_unsigned_bin(&key.N, tmp); +printf("N == \n"); +for (cnt = 0; cnt < len; ) { + printf("%02x ", tmp[cnt]); + if (!(++cnt & 15)) printf("\n"); +} + +len = mp_unsigned_bin_size(&key.p); +mp_to_unsigned_bin(&key.p, tmp); +printf("p == \n"); +for (cnt = 0; cnt < len; ) { + printf("%02x ", tmp[cnt]); + if (!(++cnt & 15)) printf("\n"); +} + +len = mp_unsigned_bin_size(&key.q); +mp_to_unsigned_bin(&key.q, tmp); +printf("\nq == \n"); +for (cnt = 0; cnt < len; ) { + printf("%02x ", tmp[cnt]); + if (!(++cnt & 15)) printf("\n"); +} +printf("\n"); + + + return 1; + } + if (cnt != 9) { + rsa_free(&key); + } + } /* test PKCS #1 v1.5 */ for (cnt = 0; cnt < 4; cnt++) { for (rsa_msgsize = 1; rsa_msgsize <= 117; rsa_msgsize++) { /* make a random key/msg */ - yarrow_read(in, rsa_msgsize, &test_yarrow); + yarrow_read(in, rsa_msgsize, &yarrow_prng); len = sizeof(out); len2 = rsa_msgsize; /* encrypt */ - DO(rsa_v15_encrypt_key(in, rsa_msgsize, out, &len, &test_yarrow, prng_idx, &key)); + DO(rsa_v15_encrypt_key(in, rsa_msgsize, out, &len, &yarrow_prng, prng_idx, &key)); DO(rsa_v15_decrypt_key(out, len, tmp, rsa_msgsize, &stat, &key)); if (stat != 1 || memcmp(tmp, in, rsa_msgsize)) { printf("PKCS #1 v1.5 encrypt/decrypt failure (rsa_msgsize: %lu, stat: %d)\n", rsa_msgsize, stat); @@ -57,12 +93,12 @@ int rsa_test(void) for (cnt = 0; cnt < 4; cnt++) { for (rsa_msgsize = 1; rsa_msgsize <= 86; rsa_msgsize++) { /* make a random key/msg */ - yarrow_read(in, rsa_msgsize, &test_yarrow); + yarrow_read(in, rsa_msgsize, &yarrow_prng); len = sizeof(out); len2 = rsa_msgsize; - DO(rsa_encrypt_key(in, rsa_msgsize, out, &len, NULL, 0, &test_yarrow, prng_idx, hash_idx, &key)); + DO(rsa_encrypt_key(in, rsa_msgsize, out, &len, NULL, 0, &yarrow_prng, prng_idx, hash_idx, &key)); /* change a byte */ out[8] ^= 1; DO(rsa_decrypt_key(out, len, tmp, &len2, NULL, 0, hash_idx, &stat2, &key)); @@ -107,7 +143,7 @@ int rsa_test(void) for (rsa_msgsize = 1; rsa_msgsize <= 86; rsa_msgsize++) { len = sizeof(out); len2 = rsa_msgsize; - DO(rsa_encrypt_key(in, rsa_msgsize, out, &len, lparam, sizeof(lparam), &test_yarrow, prng_idx, hash_idx, &key)); + DO(rsa_encrypt_key(in, rsa_msgsize, out, &len, lparam, sizeof(lparam), &yarrow_prng, prng_idx, hash_idx, &key)); /* change a byte */ out[8] ^= 1; DO(rsa_decrypt_key(out, len, tmp, &len2, lparam, sizeof(lparam), hash_idx, &stat2, &key)); @@ -132,7 +168,7 @@ 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)); + DO(rsa_sign_hash(in, 20, out, &len, &yarrow_prng, prng_idx, hash_idx, 0, &key)); /* export key and import as both private and public */ len2 = sizeof(tmp); @@ -190,7 +226,7 @@ int rsa_test(void) /* 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_sign_hash(in, 20, out, &len, &yarrow_prng, prng_idx, hash_idx, 8, &privKey)); DO(rsa_verify_hash(out, len, in, 20, hash_idx, 8, &stat, &pubKey)); /* change a byte */ in[0] ^= 1; diff --git a/demos/test/store_test.c b/testprof/store_test.c similarity index 95% rename from demos/test/store_test.c rename to testprof/store_test.c index e033594..41b2f92 100644 --- a/demos/test/store_test.c +++ b/testprof/store_test.c @@ -1,11 +1,11 @@ -#include "test.h" +#include /* Test store/load macros with offsets */ int store_test(void) { unsigned char buf[24]; - unsigned long L, L1; int y; + ulong32 L, L1; ulong64 LL, LL1; L = 0x12345678UL; diff --git a/testprof/test.c b/testprof/test.c new file mode 100644 index 0000000..9f6df71 --- /dev/null +++ b/testprof/test.c @@ -0,0 +1,9 @@ +#include + +void run_cmd(int res, int line, char *file, char *cmd) +{ + if (res != CRYPT_OK) { + fprintf(stderr, "%s (%d)\n%s:%d:%s\n", error_to_string(res), res, file, line, cmd); + exit(EXIT_FAILURE); + } +} diff --git a/testprof/tomcrypt_test.h b/testprof/tomcrypt_test.h new file mode 100644 index 0000000..fc28430 --- /dev/null +++ b/testprof/tomcrypt_test.h @@ -0,0 +1,73 @@ + +#ifndef __TEST_H_ +#define __TEST_H_ + +#include + +/* enable stack testing */ +// #define STACK_TEST + +/* stack testing, define this if stack usage goes downwards [e.g. x86] */ +#define STACK_DOWN + +typedef struct { + char *name, *prov, *req; + int (*entry)(void); +} test_entry; + +extern prng_state yarrow_prng; + +void run_cmd(int res, int line, char *file, char *cmd); +#define DO(x) { run_cmd((x), __LINE__, __FILE__, #x); } + +/* TESTS */ +int cipher_hash_test(void); +int modes_test(void); +int mac_test(void); +int pkcs_1_test(void); +int store_test(void); +int rsa_test(void); +int ecc_tests(void); +int dsa_test(void); +int dh_tests(void); +int der_tests(void); + +/* timing */ +#define KTIMES 25 +#define TIMES 100000 + +extern struct list { + int id; + unsigned long spd1, spd2, avg; +} results[]; + +extern int no_results; + +int sorter(const void *a, const void *b); +void tally_results(int type); +ulong64 rdtsc (void); + +void t_start(void); +ulong64 t_read(void); +void init_timer(void); + +/* register default algs */ +void reg_algs(void); +int time_keysched(void); +int time_cipher(void); +int time_cipher2(void); +int time_cipher3(void); +int time_hash(void); +void time_mult(void); +void time_sqr(void); +void time_prng(void); +void time_rsa(void); +void time_ecc(void); +void time_dh(void); +void time_macs_(unsigned long MAC_SIZE); +void time_macs(void); +void time_encmacs(void); + + + +#endif diff --git a/demos/x86_prof.c b/testprof/x86_prof.c similarity index 61% rename from demos/x86_prof.c rename to testprof/x86_prof.c index f6ba8a8..edccf55 100644 --- a/demos/x86_prof.c +++ b/testprof/x86_prof.c @@ -1,15 +1,9 @@ -#include +#include -#define KTIMES 25 -#define TIMES 100000 - -struct list { - int id; - unsigned long spd1, spd2, avg; -} results[100]; +prng_state yarrow_prng; +struct list results[100]; int no_results; - int sorter(const void *a, const void *b) { const struct list *A, *B; @@ -35,7 +29,7 @@ void tally_results(int type) } else if (type == 1) { for (x = 0; x < no_results; x++) { printf - ("%-20s[%2d]: Encrypt at %5lu, Decrypt at %5lu\n", cipher_descriptor[results[x].id].name, cipher_descriptor[results[x].id].ID, results[x].spd1, results[x].spd2); + ("%-20s[%3d]: Encrypt at %5lu, Decrypt at %5lu\n", cipher_descriptor[results[x].id].name, cipher_descriptor[results[x].id].ID, results[x].spd1, results[x].spd2); } } else { for (x = 0; x < no_results; x++) { @@ -46,12 +40,16 @@ void tally_results(int type) } /* RDTSC from Scott Duplichan */ -static ulong64 rdtsc (void) +ulong64 rdtsc (void) { #if defined __GNUC__ - #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"); + #ifdef INTEL_CC + ulong64 a; + asm ( " rdtsc ":"=A"(a)); + return a; + #elif defined(__i386__) || defined(__x86_64__) + ulong64 a; + asm __volatile__ ("rdtsc\nmovl %%eax,(%0)\nmovl %%edx,4(%0)\n"::"r"(&a):"%eax","%edx"); return a; #else /* gcc-IA64 version */ unsigned long result; @@ -76,8 +74,7 @@ static ulong64 rdtsc (void) #endif } -ulong64 timer, skew = 0; -prng_state prng; +static ulong64 timer, skew = 0; void t_start(void) { @@ -99,10 +96,10 @@ void init_timer(void) t_start(); t1 = t_read(); t3 = t_read(); - t2 = t_read() - t1; + t2 = (t_read() - t1)>>1; - c1 = (c1 > t1) ? t1 : c1; - c2 = (c2 > t2) ? t2 : c2; + c1 = (t1 > c1) ? t1 : c1; + c2 = (t2 > c2) ? t2 : c2; } skew = c2 - c1; printf("Clock Skew: %lu\n", (unsigned long)skew); @@ -220,7 +217,7 @@ register_prng(&rc4_desc); register_prng(&sober128_desc); #endif -rng_make_prng(128, find_prng("yarrow"), &prng, NULL); +rng_make_prng(128, find_prng("yarrow"), &yarrow_prng, NULL); } int time_keysched(void) @@ -241,7 +238,7 @@ int time_keysched(void) kl = cipher_descriptor[x].min_key_length; c1 = (ulong64)-1; for (y1 = 0; y1 < KTIMES; y1++) { - yarrow_read(key, kl, &prng); + yarrow_read(key, kl, &yarrow_prng); t_start(); DO1(key); t1 = t_read(); @@ -263,16 +260,14 @@ int time_cipher(void) { unsigned long x, y1; ulong64 t1, t2, c1, c2, a1, a2; - symmetric_key skey; - void (*func) (const unsigned char *, unsigned char *, symmetric_key *); - unsigned char key[MAXBLOCKSIZE], pt[MAXBLOCKSIZE]; + symmetric_ECB ecb; + unsigned char key[MAXBLOCKSIZE], pt[4096]; int err; printf ("\n\nECB Time Trials for the Symmetric Ciphers:\n"); no_results = 0; for (x = 0; cipher_descriptor[x].name != NULL; x++) { - cipher_descriptor[x].setup (key, cipher_descriptor[x].min_key_length, 0, - &skey); + ecb_start(x, key, cipher_descriptor[x].min_key_length, 0, &ecb); /* sanity check on cipher */ if ((err = cipher_descriptor[x].test()) != CRYPT_OK) { @@ -280,12 +275,11 @@ int time_cipher(void) exit(EXIT_FAILURE); } -#define DO1 func(pt,pt,&skey); +#define DO1 ecb_encrypt(pt, pt, sizeof(pt), &ecb); #define DO2 DO1 DO1 - func = cipher_descriptor[x].ecb_encrypt; c1 = c2 = (ulong64)-1; - for (y1 = 0; y1 < TIMES; y1++) { + for (y1 = 0; y1 < 100; y1++) { t_start(); DO1; t1 = t_read(); @@ -298,10 +292,13 @@ int time_cipher(void) } a1 = c2 - c1 - skew; +#undef DO1 +#undef DO2 +#define DO1 ecb_decrypt(pt, pt, sizeof(pt), &ecb); +#define DO2 DO1 DO1 - func = cipher_descriptor[x].ecb_decrypt; c1 = c2 = (ulong64)-1; - for (y1 = 0; y1 < TIMES; y1++) { + for (y1 = 0; y1 < 100; y1++) { t_start(); DO1; t1 = t_read(); @@ -315,8 +312,8 @@ int time_cipher(void) a2 = c2 - c1 - skew; results[no_results].id = x; - results[no_results].spd1 = a1/cipher_descriptor[x].block_length; - results[no_results].spd2 = a2/cipher_descriptor[x].block_length;; + results[no_results].spd1 = a1/(sizeof(pt)/cipher_descriptor[x].block_length); + results[no_results].spd2 = a2/(sizeof(pt)/cipher_descriptor[x].block_length); results[no_results].avg = (results[no_results].spd1 + results[no_results].spd2+1)/2; ++no_results; printf("."); fflush(stdout); @@ -329,6 +326,154 @@ int time_cipher(void) return 0; } +#ifdef CBC +int time_cipher2(void) +{ + unsigned long x, y1; + ulong64 t1, t2, c1, c2, a1, a2; + symmetric_CBC cbc; + unsigned char key[MAXBLOCKSIZE], pt[4096]; + int err; + + printf ("\n\nCBC Time Trials for the Symmetric Ciphers:\n"); + no_results = 0; + for (x = 0; cipher_descriptor[x].name != NULL; x++) { + cbc_start(x, pt, key, cipher_descriptor[x].min_key_length, 0, &cbc); + + /* sanity check on cipher */ + if ((err = cipher_descriptor[x].test()) != CRYPT_OK) { + fprintf(stderr, "\n\nERROR: Cipher %s failed self-test %s\n", cipher_descriptor[x].name, error_to_string(err)); + exit(EXIT_FAILURE); + } + +#define DO1 cbc_encrypt(pt, pt, sizeof(pt), &cbc); +#define DO2 DO1 DO1 + + c1 = c2 = (ulong64)-1; + for (y1 = 0; y1 < 100; y1++) { + t_start(); + DO1; + t1 = t_read(); + DO2; + t2 = t_read(); + t2 -= t1; + + c1 = (t1 > c1 ? c1 : t1); + c2 = (t2 > c2 ? c2 : t2); + } + a1 = c2 - c1 - skew; + +#undef DO1 +#undef DO2 +#define DO1 cbc_decrypt(pt, pt, sizeof(pt), &cbc); +#define DO2 DO1 DO1 + + c1 = c2 = (ulong64)-1; + for (y1 = 0; y1 < 100; y1++) { + t_start(); + DO1; + t1 = t_read(); + DO2; + t2 = t_read(); + t2 -= t1; + + c1 = (t1 > c1 ? c1 : t1); + c2 = (t2 > c2 ? c2 : t2); + } + a2 = c2 - c1 - skew; + + results[no_results].id = x; + results[no_results].spd1 = a1/(sizeof(pt)/cipher_descriptor[x].block_length); + results[no_results].spd2 = a2/(sizeof(pt)/cipher_descriptor[x].block_length); + results[no_results].avg = (results[no_results].spd1 + results[no_results].spd2+1)/2; + ++no_results; + printf("."); fflush(stdout); + +#undef DO2 +#undef DO1 + } + tally_results(1); + + return 0; +} +#else +int time_cipher2(void) { printf("NO CBC\n"); return 0; } +#endif + +#ifdef CTR +int time_cipher3(void) +{ + unsigned long x, y1; + ulong64 t1, t2, c1, c2, a1, a2; + symmetric_CTR ctr; + unsigned char key[MAXBLOCKSIZE], pt[4096]; + int err; + + printf ("\n\nCTR Time Trials for the Symmetric Ciphers:\n"); + no_results = 0; + for (x = 0; cipher_descriptor[x].name != NULL; x++) { + ctr_start(x, pt, key, cipher_descriptor[x].min_key_length, 0, &ctr); + + /* sanity check on cipher */ + if ((err = cipher_descriptor[x].test()) != CRYPT_OK) { + fprintf(stderr, "\n\nERROR: Cipher %s failed self-test %s\n", cipher_descriptor[x].name, error_to_string(err)); + exit(EXIT_FAILURE); + } + +#define DO1 ctr_encrypt(pt, pt, sizeof(pt), &ctr); +#define DO2 DO1 DO1 + + c1 = c2 = (ulong64)-1; + for (y1 = 0; y1 < 100; y1++) { + t_start(); + DO1; + t1 = t_read(); + DO2; + t2 = t_read(); + t2 -= t1; + + c1 = (t1 > c1 ? c1 : t1); + c2 = (t2 > c2 ? c2 : t2); + } + a1 = c2 - c1 - skew; + +#undef DO1 +#undef DO2 +#define DO1 ctr_decrypt(pt, pt, sizeof(pt), &ctr); +#define DO2 DO1 DO1 + + c1 = c2 = (ulong64)-1; + for (y1 = 0; y1 < 100; y1++) { + t_start(); + DO1; + t1 = t_read(); + DO2; + t2 = t_read(); + t2 -= t1; + + c1 = (t1 > c1 ? c1 : t1); + c2 = (t2 > c2 ? c2 : t2); + } + a2 = c2 - c1 - skew; + + results[no_results].id = x; + results[no_results].spd1 = a1/(sizeof(pt)/cipher_descriptor[x].block_length); + results[no_results].spd2 = a2/(sizeof(pt)/cipher_descriptor[x].block_length); + results[no_results].avg = (results[no_results].spd1 + results[no_results].spd2+1)/2; + ++no_results; + printf("."); fflush(stdout); + +#undef DO2 +#undef DO1 + } + tally_results(1); + + return 0; +} +#else +int time_cipher3(void) { printf("NO CTR\n"); return 0; } +#endif + int time_hash(void) { unsigned long x, y1, len; @@ -380,6 +525,7 @@ int time_hash(void) return 0; } +#ifdef MPI void time_mult(void) { ulong64 t1, t2; @@ -409,7 +555,7 @@ void time_mult(void) #undef DO1 #undef DO2 -} +} void time_sqr(void) { @@ -439,7 +585,11 @@ void time_sqr(void) #undef DO1 #undef DO2 -} +} +#else +void time_mult(void) { printf("NO MULT\n"); } +void time_sqr(void) { printf("NO SQR\n"); } +#endif void time_prng(void) { @@ -492,7 +642,8 @@ void time_prng(void) } } - + +#ifdef MRSA /* time various RSA operations */ void time_rsa(void) { @@ -507,7 +658,7 @@ void time_rsa(void) for (y = 0; y < 16; y++) { t_start(); t1 = t_read(); - if ((err = rsa_make_key(&prng, find_prng("yarrow"), x/8, 65537, &key)) != CRYPT_OK) { + if ((err = rsa_make_key(&yarrow_prng, find_prng("yarrow"), x/8, 65537, &key)) != CRYPT_OK) { fprintf(stderr, "\n\nrsa_make_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK)); exit(EXIT_FAILURE); } @@ -526,7 +677,7 @@ void time_rsa(void) t_start(); t1 = t_read(); z = sizeof(buf[1]); - if ((err = rsa_encrypt_key(buf[0], 32, buf[1], &z, "testprog", 8, &prng, + if ((err = rsa_encrypt_key(buf[0], 32, buf[1], &z, "testprog", 8, &yarrow_prng, find_prng("yarrow"), find_hash("sha1"), &key)) != CRYPT_OK) { fprintf(stderr, "\n\nrsa_encrypt_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK)); @@ -558,7 +709,11 @@ void time_rsa(void) rsa_free(&key); } } +#else +void time_rsa(void) { printf("NO RSA\n"); } +#endif +#ifdef MECC /* time various ECC operations */ void time_ecc(void) { @@ -574,7 +729,7 @@ void time_ecc(void) for (y = 0; y < 16; y++) { t_start(); t1 = t_read(); - if ((err = ecc_make_key(&prng, find_prng("yarrow"), x, &key)) != CRYPT_OK) { + if ((err = ecc_make_key(&yarrow_prng, find_prng("yarrow"), x, &key)) != CRYPT_OK) { fprintf(stderr, "\n\necc_make_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK)); exit(EXIT_FAILURE); } @@ -593,7 +748,7 @@ void time_ecc(void) t_start(); t1 = t_read(); z = sizeof(buf[1]); - if ((err = ecc_encrypt_key(buf[0], 20, buf[1], &z, &prng, find_prng("yarrow"), find_hash("sha1"), + if ((err = ecc_encrypt_key(buf[0], 20, buf[1], &z, &yarrow_prng, find_prng("yarrow"), find_hash("sha1"), &key)) != CRYPT_OK) { fprintf(stderr, "\n\necc_encrypt_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK)); exit(EXIT_FAILURE); @@ -606,7 +761,11 @@ void time_ecc(void) ecc_free(&key); } } +#else +void time_ecc(void) { printf("NO ECC\n"); } +#endif +#ifdef MDH /* time various DH operations */ void time_dh(void) { @@ -622,7 +781,7 @@ void time_dh(void) for (y = 0; y < 16; y++) { t_start(); t1 = t_read(); - if ((err = dh_make_key(&prng, find_prng("yarrow"), x, &key)) != CRYPT_OK) { + if ((err = dh_make_key(&yarrow_prng, find_prng("yarrow"), x, &key)) != CRYPT_OK) { fprintf(stderr, "\n\ndh_make_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK)); exit(EXIT_FAILURE); } @@ -641,7 +800,7 @@ void time_dh(void) t_start(); t1 = t_read(); z = sizeof(buf[1]); - if ((err = dh_encrypt_key(buf[0], 20, buf[1], &z, &prng, find_prng("yarrow"), find_hash("sha1"), + if ((err = dh_encrypt_key(buf[0], 20, buf[1], &z, &yarrow_prng, find_prng("yarrow"), find_hash("sha1"), &key)) != CRYPT_OK) { fprintf(stderr, "\n\ndh_encrypt_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK)); exit(EXIT_FAILURE); @@ -654,9 +813,11 @@ void time_dh(void) dh_free(&key); } } +#else +void time_dh(void) { printf("NO DH\n"); } +#endif -#define MAC_SIZE 32 -void time_macs(void) +void time_macs_(unsigned long MAC_SIZE) { unsigned char *buf, key[16], tag[16]; ulong64 t1, t2; @@ -674,9 +835,10 @@ void time_macs(void) cipher_idx = find_cipher("aes"); hash_idx = find_hash("md5"); - yarrow_read(buf, MAC_SIZE*1024, &prng); - yarrow_read(key, 16, &prng); + yarrow_read(buf, MAC_SIZE*1024, &yarrow_prng); + yarrow_read(key, 16, &yarrow_prng); +#ifdef OMAC t2 = -1; for (x = 0; x < 10000; x++) { t_start(); @@ -690,7 +852,9 @@ void time_macs(void) if (t1 < t2) t2 = t1; } printf("OMAC-AES\t\t%9llu\n", t2/(MAC_SIZE*1024)); +#endif +#ifdef PMAC t2 = -1; for (x = 0; x < 10000; x++) { t_start(); @@ -704,7 +868,25 @@ void time_macs(void) if (t1 < t2) t2 = t1; } printf("PMAC-AES\t\t%9llu\n", t2/(MAC_SIZE*1024)); +#endif +#ifdef PELICAN + t2 = -1; + for (x = 0; x < 10000; x++) { + t_start(); + t1 = t_read(); + z = 16; + if ((err = pelican_memory(key, 16, buf, MAC_SIZE*1024, tag)) != CRYPT_OK) { + fprintf(stderr, "\n\npelican error... %s\n", error_to_string(err)); + exit(EXIT_FAILURE); + } + t1 = t_read() - t1; + if (t1 < t2) t2 = t1; + } + printf("PELICAN \t\t%9llu\n", t2/(MAC_SIZE*1024)); +#endif + +#ifdef HMAC t2 = -1; for (x = 0; x < 10000; x++) { t_start(); @@ -718,28 +900,145 @@ void time_macs(void) if (t1 < t2) t2 = t1; } printf("HMAC-MD5\t\t%9llu\n", t2/(MAC_SIZE*1024)); +#endif XFREE(buf); } -int main(void) +void time_macs(void) { - reg_algs(); - - printf("Timings for ciphers and hashes. Times are listed as cycles per byte processed.\n\n"); - -// init_timer(); - time_mult(); - time_sqr(); - time_rsa(); - time_dh(); - time_ecc(); - time_prng(); - time_cipher(); - time_keysched(); - time_hash(); - time_macs(); - - return EXIT_SUCCESS; + time_macs_(1); + time_macs_(4); + time_macs_(32); } +void time_encmacs_(unsigned long MAC_SIZE) +{ + unsigned char *buf, IV[16], key[16], tag[16]; + ulong64 t1, t2; + unsigned long x, z; + int err, cipher_idx; + + printf("\nENC+MAC Timings (zero byte AAD, 16 byte IV, cycles/byte on %dKB blocks):\n", MAC_SIZE); + + buf = XMALLOC(MAC_SIZE*1024); + if (buf == NULL) { + fprintf(stderr, "\n\nout of heap yo\n\n"); + exit(EXIT_FAILURE); + } + + cipher_idx = find_cipher("aes"); + + yarrow_read(buf, MAC_SIZE*1024, &yarrow_prng); + yarrow_read(key, 16, &yarrow_prng); + yarrow_read(IV, 16, &yarrow_prng); + +#ifdef EAX_MODE + t2 = -1; + for (x = 0; x < 10000; x++) { + t_start(); + t1 = t_read(); + z = 16; + if ((err = eax_encrypt_authenticate_memory(cipher_idx, key, 16, IV, 16, NULL, 0, buf, MAC_SIZE*1024, buf, tag, &z)) != CRYPT_OK) { + fprintf(stderr, "\nEAX error... %s\n", error_to_string(err)); + exit(EXIT_FAILURE); + } + t1 = t_read() - t1; + if (t1 < t2) t2 = t1; + } + printf("EAX \t\t%9llu\n", t2/(MAC_SIZE*1024)); +#endif + +#ifdef OCB_MODE + t2 = -1; + for (x = 0; x < 10000; x++) { + t_start(); + t1 = t_read(); + z = 16; + if ((err = ocb_encrypt_authenticate_memory(cipher_idx, key, 16, IV, buf, MAC_SIZE*1024, buf, tag, &z)) != CRYPT_OK) { + fprintf(stderr, "\nOCB error... %s\n", error_to_string(err)); + exit(EXIT_FAILURE); + } + t1 = t_read() - t1; + if (t1 < t2) t2 = t1; + } + printf("OCB \t\t%9llu\n", t2/(MAC_SIZE*1024)); +#endif + +#ifdef CCM_MODE + t2 = -1; + for (x = 0; x < 10000; x++) { + t_start(); + t1 = t_read(); + z = 16; + if ((err = ccm_memory(cipher_idx, key, 16, IV, 16, NULL, 0, buf, MAC_SIZE*1024, buf, tag, &z, CCM_ENCRYPT)) != CRYPT_OK) { + fprintf(stderr, "\nCCM error... %s\n", error_to_string(err)); + exit(EXIT_FAILURE); + } + t1 = t_read() - t1; + if (t1 < t2) t2 = t1; + } + printf("CCM \t\t%9llu\n", t2/(MAC_SIZE*1024)); +#endif + +#ifdef GCM_MODE + t2 = -1; + for (x = 0; x < 100; x++) { + t_start(); + t1 = t_read(); + z = 16; + if ((err = gcm_memory(cipher_idx, key, 16, IV, 16, NULL, 0, buf, MAC_SIZE*1024, buf, tag, &z, GCM_ENCRYPT)) != CRYPT_OK) { + fprintf(stderr, "\nGCM error... %s\n", error_to_string(err)); + exit(EXIT_FAILURE); + } + t1 = t_read() - t1; + if (t1 < t2) t2 = t1; + } + printf("GCM (no-precomp)\t%9llu\n", t2/(MAC_SIZE*1024)); + + { + gcm_state gcm; + + if ((err = gcm_init(&gcm, cipher_idx, key, 16)) != CRYPT_OK) { printf("gcm_init: %s\n", error_to_string(err)); exit(EXIT_FAILURE); } + t2 = -1; + for (x = 0; x < 10000; x++) { + t_start(); + t1 = t_read(); + z = 16; + if ((err = gcm_reset(&gcm)) != CRYPT_OK) { + fprintf(stderr, "\nGCM error[%d]... %s\n", __LINE__, error_to_string(err)); + exit(EXIT_FAILURE); + } + if ((err = gcm_add_iv(&gcm, IV, 16)) != CRYPT_OK) { + fprintf(stderr, "\nGCM error[%d]... %s\n", __LINE__, error_to_string(err)); + exit(EXIT_FAILURE); + } + if ((err = gcm_add_aad(&gcm, NULL, 0)) != CRYPT_OK) { + fprintf(stderr, "\nGCM error[%d]... %s\n", __LINE__, error_to_string(err)); + exit(EXIT_FAILURE); + } + if ((err = gcm_process(&gcm, buf, MAC_SIZE*1024, buf, GCM_ENCRYPT)) != CRYPT_OK) { + fprintf(stderr, "\nGCM error[%d]... %s\n", __LINE__, error_to_string(err)); + exit(EXIT_FAILURE); + } + + if ((err = gcm_done(&gcm, tag, &z)) != CRYPT_OK) { + fprintf(stderr, "\nGCM error[%d]... %s\n", __LINE__, error_to_string(err)); + exit(EXIT_FAILURE); + } + t1 = t_read() - t1; + if (t1 < t2) t2 = t1; + } + printf("GCM (precomp)\t%9llu\n", t2/(MAC_SIZE*1024)); + } + +#endif + +} + +void time_encmacs(void) +{ + time_encmacs_(1); + time_encmacs_(4); + time_encmacs_(32); +}